You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
asciinema.org/app/assets/javascripts/player/movie.js.coffee

233 lines
4.7 KiB
CoffeeScript

class AsciiIo.Movie
MIN_DELAY: 0.01
constructor: (@model, @options) ->
@reset()
@startTimeReporter()
_.extend(this, Backbone.Events)
reset: ->
@frameNo = 0
@dataIndex = 0
@completedFramesTime = 0
@playing = false
@lastFrameAt = undefined
@framesProcessed = 0
@clearPauseState()
now: ->
(new Date()).getTime()
isLoaded: ->
@model.get('escaped_stdout_data') != undefined
load: ->
@model.fetch
success: =>
if typeof window.Worker == 'function'
worker = new Worker('/uncompress.js')
worker.onmessage = (event) =>
@_data = event.data
@trigger('movie-loaded', @model)
data = @model.get('escaped_stdout_data')
data = atob(data)
worker.postMessage(data)
else
@trigger('movie-loaded', @model)
timing: ->
@model.get('stdout_timing_data')
data: ->
unless @_data
# fallback for webworker
d = @model.get('escaped_stdout_data')
d = atob(d)
d = ArchUtils.bz2.decode(d)
@_data = d
@_data
play: ->
return if @isPlaying()
if @isFinished()
@restart()
else if @isPaused()
@resume()
else
@start()
start: ->
if @options.benchmark
@startedAt = @now()
@playing = true
@lastFrameAt = @now()
@nextFrame()
stop: ->
clearInterval @nextFrameTimeoutId
@playing = false
now = @now()
resumedAt = @resumedAt or @lastFrameAt
currentWaitTime = now - resumedAt
@totalFrameWaitTime += currentWaitTime
@pausedAt = now
restart: ->
@reset()
@start()
@startTimeReporter()
pause: ->
return if @isPaused()
@stop()
@trigger('movie-playback-paused')
resume: ->
return if @isPlaying()
@playing = true
@resumedAt = @now()
frame = @timing()[@frameNo]
[delay, count] = frame
delayMs = delay * 1000
delayLeft = delayMs - @totalFrameWaitTime
@processFrameWithDelay(delayLeft)
@trigger('movie-playback-resumed')
togglePlay: ->
if @isPlaying() then @pause() else @play()
isPlaying: ->
@playing
isPaused: ->
!@isPlaying() and !@isFinished() and @frameNo > 0
isFinished: ->
!@isPlaying() and @isLoaded() and @frameNo >= @timing().length
seek: (percent) ->
13 years ago
@stop()
@rewindTo(percent)
13 years ago
@start()
rewindTo: (requestedPercent) ->
percent = 0
frameNo = 0
time = 0
totalCount = 0
duration = @model.get('duration')
while percent < requestedPercent
[delay, count] = @timing()[frameNo]
time += delay
totalCount += count
frameNo += 1
percent = 100 * time / duration
@frameNo = frameNo
@completedFramesTime = time * 1000
@dataIndex = totalCount
@clearPauseState()
13 years ago
data = @data().slice(0, totalCount)
@trigger('movie-frame', data)
startTimeReporter: ->
@timeReportId = setInterval(
=> @trigger('movie-time', @currentTime())
100
)
stopTimeReporter: ->
clearInterval @timeReportId
currentTime: ->
@completedFramesTime + @currentFrameTime()
currentFrameTime: ->
if @isPlaying()
@playingFrameTime()
else if @isPaused()
@pausedFrameTime()
else
0
playingFrameTime: ->
if @frameWasPaused()
@currentFrameWithPauseTime()
else
@currentFrameWithNoPauseTime()
frameWasPaused: ->
!!@pausedAt
currentFrameWithPauseTime: ->
@totalFrameWaitTime + @sinceResumeTime()
currentFrameWithNoPauseTime: ->
@now() - @lastFrameAt
sinceResumeTime: ->
@now() - @resumedAt
pausedFrameTime: ->
@totalFrameWaitTime
clearPauseState: ->
@pausedAt = undefined
@resumedAt = undefined
@totalFrameWaitTime = 0
nextFrame: ->
if frame = @timing()[@frameNo]
[delay, count] = frame
if delay <= @MIN_DELAY and @framesProcessed < 100
@framesProcessed += 1
@processFrame()
else
@framesProcessed = 0
realDelay = delay * 1000 * (1.0 / @options.speed)
@processFrameWithDelay(realDelay)
true
else
@playing = false
@stopTimeReporter()
@trigger('movie-finished')
if @options.benchmark
console.log "finished in #{(@now() - @startedAt) / 1000.0}s"
false
13 years ago
processFrameWithDelay: (delay) ->
@nextFrameTimeoutId = setTimeout(
=>
@trigger('movie-awake')
@processFrame()
delay
)
13 years ago
processFrame: ->
frame = @timing()[@frameNo]
[delay, count] = frame
13 years ago
frameData = @data().slice(@dataIndex, @dataIndex + count)
@trigger('movie-frame', frameData)
13 years ago
@frameNo += 1
@dataIndex += count
@completedFramesTime += delay * 1000
@lastFrameAt = @now()
13 years ago
@clearPauseState()
@nextFrame()