--!parent
--!encoding=utf-8
-- ************************************************************************
-- Software: VideoSync
-- Version: 0.1
-- Date: 2016-04-25
-- Author: Valentin Schmidt
--
-- Requirements/Dependencies:
-- - Xtra "AVMedia"
--
-- Loads and plays synced videos.
-- Videos can optionally be synced to a master audio (otherwise pass VOID
-- as parameter <audioSyncFile> to constructor).
--
-- ************************************************************************
property _axList
property _videosLoaded
property _audio
property _cbReadyHandler
property _cbReadyTarget
----------------------------------------
-- Constructor
-- @param {list} videoList
-- @param {string|VOID} audioSyncFile
-- @param {symbol} cbReadyHandler
-- @param {object} cbReadyTarget - optional, default = _movie
--
-- <videoList> is a list of propLists, with each propList having properties:
-- - #filename: path to video file
-- - #rect: rect of corresponding video player on the screen
-- - #mask: windowMask of corresponding video player (optional, default=0)
--
-- <audioSyncFile> is the path to an audioFile used as master clock (pass VOID
-- if not syncing to audio).
--
-- <cbReadyHandler> (of object <cbReadyTarget>) is the callback that will be notified
-- as soon as all videos (and master audio) are loaded and ready to be played.
----------------------------------------
on new (me, videoList, audioSyncFile, cbReadyHandler, cbReadyTarget)
if voidP(cbReadyTarget) then cbReadyTarget=_movie
me._cbReadyHandler = cbReadyHandler
me._cbReadyTarget = cbReadyTarget
me._axList = []
me._videosLoaded = 0
if stringP(audioSyncFile) then
me._audio = xtra("AVMedia").new()
me._audio.audioOpen(audioSyncFile)
end if
repeat with videoProps in videoList
ax = xtra("AVMedia").new()
ax.videoSetReadyStatusChangeCallback(#_videoReady, me)
fn = videoProps[#filename]
rect = videoProps[#rect]
mask = videoProps[#mask]
if voidP(mask) then mask = 0
ax.videoOpen(fn, rect, mask)
if not voidP(me._audio) then
ax.videoSyncToAudio()
end if
me._axList.add(ax)
end repeat
return me
end
----------------------------------------
--
----------------------------------------
on destroy (me)
--
end
----------------------------------------
-- Starts synced playback
----------------------------------------
on play (me)
repeat with v in me._axList
-- float rate, intOrVOID time, intOrVOID hostTime, *timescale
v.videoSetRate(1.0, VOID, 0)
end repeat
if not voidP(me._audio) then
me._audio.audioPlay()
end if
end
----------------------------------------
-- CALLBACK
----------------------------------------
on _videoReady (me)
me._videosLoaded = me._videosLoaded + 1
if (me._videosLoaded>=count(me._axList)) then
call(me._cbReadyHandler, me._cbReadyTarget) -- all videos are ready
end if
end