diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Types.hx | 7 | ||||
| -rw-r--r-- | src/client/IPlayer.hx | 2 | ||||
| -rw-r--r-- | src/client/Main.hx | 11 | ||||
| -rw-r--r-- | src/client/Player.hx | 26 | ||||
| -rw-r--r-- | src/client/players/Iframe.hx | 6 | ||||
| -rw-r--r-- | src/client/players/Raw.hx | 9 | ||||
| -rw-r--r-- | src/client/players/Youtube.hx | 13 | ||||
| -rw-r--r-- | src/server/Main.hx | 21 | ||||
| -rw-r--r-- | src/server/VideoTimer.hx | 36 |
9 files changed, 119 insertions, 12 deletions
diff --git a/src/Types.hx b/src/Types.hx index 2501cc4..366b2ed 100644 --- a/src/Types.hx +++ b/src/Types.hx @@ -134,11 +134,15 @@ typedef WsEvent = { }, ?getTime:{ time:Float, - paused:Bool + ?paused:Bool, + ?rate:Float }, ?setTime:{ time:Float }, + ?setRate:{ + rate:Float + }, ?rewind:{ time:Float }, @@ -181,6 +185,7 @@ enum abstract WsEventType(String) { var Play; var GetTime; var SetTime; + var SetRate; var Rewind; var SetLeader; var PlayItem; diff --git a/src/client/IPlayer.hx b/src/client/IPlayer.hx index 4f29512..e414af5 100644 --- a/src/client/IPlayer.hx +++ b/src/client/IPlayer.hx @@ -11,4 +11,6 @@ interface IPlayer { function pause():Void; function getTime():Float; function setTime(time:Float):Void; + function getPlaybackRate():Float; + function setPlaybackRate(rate:Float):Void; } diff --git a/src/client/Main.hx b/src/client/Main.hx index f65640a..780f005 100644 --- a/src/client/Main.hx +++ b/src/client/Main.hx @@ -366,6 +366,13 @@ class Main { player.play(); case GetTime: + if (data.getTime.paused == null) data.getTime.paused = false; + if (data.getTime.rate == null) data.getTime.rate = 1; + + if (player.getPlaybackRate() != data.getTime.rate) { + player.setPlaybackRate(data.getTime.rate); + } + final newTime = data.getTime.time; final time = player.getTime(); if (isLeader()) { @@ -386,6 +393,10 @@ class Main { if (Math.abs(time - newTime) < synchThreshold) return; player.setTime(newTime); + case SetRate: + if (isLeader()) return; + player.setPlaybackRate(data.setRate.rate); + case Rewind: player.setTime(data.rewind.time); diff --git a/src/client/Player.hx b/src/client/Player.hx index 8e55b25..53a1168 100644 --- a/src/client/Player.hx +++ b/src/client/Player.hx @@ -21,6 +21,7 @@ class Player { var itemPos = 0; var isLoaded = false; var skipSetTime = false; + var skipSetRate = false; public function new(main:Main):Void { this.main = main; @@ -158,6 +159,19 @@ class Player { }); } + public function onRateChange():Void { + if (skipSetRate) { + skipSetRate = false; + return; + } + if (!main.isLeader()) return; + main.send({ + type: SetRate, setRate: { + rate: getPlaybackRate() + } + }); + } + public function addVideoItem(item:VideoItem, atEnd:Bool):Void { final url = item.url.htmlEscape(true); final itemEl = nodeFromString( @@ -322,4 +336,16 @@ class Player { player.setTime(time); } + public function getPlaybackRate():Float { + if (player == null) return 1; + return player.getPlaybackRate(); + } + + public function setPlaybackRate(rate:Float, isLocal = true):Void { + if (!main.isSyncActive) return; + if (player == null) return; + skipSetRate = isLocal; + player.setPlaybackRate(rate); + } + } diff --git a/src/client/players/Iframe.hx b/src/client/players/Iframe.hx index f0a04c5..d79196b 100644 --- a/src/client/players/Iframe.hx +++ b/src/client/players/Iframe.hx @@ -59,4 +59,10 @@ class Iframe implements IPlayer { public function setTime(time:Float):Void {} + public function getPlaybackRate():Float { + return 1; + } + + public function setPlaybackRate(rate:Float):Void {} + } diff --git a/src/client/players/Raw.hx b/src/client/players/Raw.hx index c7fa980..cd01a42 100644 --- a/src/client/players/Raw.hx +++ b/src/client/players/Raw.hx @@ -67,6 +67,7 @@ class Raw implements IPlayer { player.onPlay(); } video.onpause = player.onPause; + video.onratechange = player.onRateChange; playerEl.appendChild(video); } @@ -102,4 +103,12 @@ class Raw implements IPlayer { video.currentTime = time; } + public function getPlaybackRate():Float { + return video.playbackRate; + } + + public function setPlaybackRate(rate:Float):Void { + video.playbackRate = rate; + } + } diff --git a/src/client/players/Youtube.hx b/src/client/players/Youtube.hx index f582ba7..eff407e 100644 --- a/src/client/players/Youtube.hx +++ b/src/client/players/Youtube.hx @@ -208,7 +208,10 @@ class Youtube implements IPlayer { player.onSetTime(); case CUED: } - } + }, + onPlaybackRateChange: e -> { + player.onRateChange(); + }, } }); } @@ -239,4 +242,12 @@ class Youtube implements IPlayer { youtube.seekTo(time, true); } + public function getPlaybackRate():Float { + return youtube.getPlaybackRate(); + } + + public function setPlaybackRate(rate:Float):Void { + youtube.setPlaybackRate(rate); + } + } diff --git a/src/server/Main.hx b/src/server/Main.hx index f056ac6..5142f48 100644 --- a/src/server/Main.hx +++ b/src/server/Main.hx @@ -438,11 +438,17 @@ class Main { }); return; } - send(client, { + final obj:WsEvent = { type: GetTime, getTime: { - time: videoTimer.getTime(), - paused: videoTimer.isPaused() - }}); + time: videoTimer.getTime() + } + }; + if (videoTimer.isPaused()) obj.getTime.paused = true; + if (videoTimer.getRate() != 1) { + if (!clients.hasLeader()) videoTimer.setRate(1); + obj.getTime.rate = videoTimer.getRate(); + } + send(client, obj); case SetTime: if (videoList.length == 0) return; @@ -450,6 +456,12 @@ class Main { videoTimer.setTime(data.setTime.time); broadcastExcept(client, data); + case SetRate: + if (videoList.length == 0) return; + if (!client.isLeader) return; + videoTimer.setRate(data.setRate.rate); + broadcastExcept(client, data); + case Rewind: if (!checkPermission(client, RewindPerm)) return; if (videoList.length == 0) return; @@ -474,6 +486,7 @@ class Main { if (videoList.length == 0) return; if (!clients.hasLeader()) { if (videoTimer.isPaused()) videoTimer.play(); + videoTimer.setRate(1); broadcast({ type: Play, play: { time: videoTimer.getTime() diff --git a/src/server/VideoTimer.hx b/src/server/VideoTimer.hx index 4bc29db..508b97b 100644 --- a/src/server/VideoTimer.hx +++ b/src/server/VideoTimer.hx @@ -1,19 +1,22 @@ package server; -import haxe.Timer; +import haxe.Timer.stamp; class VideoTimer { public var isStarted(default, null) = false; var startTime = 0.0; var pauseStartTime = 0.0; + var rateStartTime = 0.0; + var rate = 1.0; public function new() {} public function start():Void { isStarted = true; - startTime = Timer.stamp(); + startTime = stamp(); pauseStartTime = 0; + rateStartTime = stamp(); } public function stop():Void { @@ -23,22 +26,26 @@ class VideoTimer { } public function pause():Void { - pauseStartTime = Timer.stamp(); + startTime += rateTime() - rateTime() * this.rate; + pauseStartTime = stamp(); + rateStartTime = 0; } public function play():Void { if (!isStarted) start(); startTime += pauseTime(); + rateStartTime = stamp(); pauseStartTime = 0; } public function getTime():Float { if (startTime == 0) return 0; - return Timer.stamp() - startTime - pauseTime(); + final time = stamp() - startTime; + return time - rateTime() + rateTime() * rate - pauseTime(); } public function setTime(secs:Float):Void { - startTime = Timer.stamp() - secs; + startTime = stamp() - secs; if (isPaused()) pause(); } @@ -46,9 +53,26 @@ class VideoTimer { return !isStarted || pauseStartTime != 0; } + public function getRate():Float { + return rate; + } + + public function setRate(rate:Float):Void { + if (!isPaused()) { + startTime += rateTime() - rateTime() * this.rate; + rateStartTime = stamp(); + } + this.rate = rate; + } + function pauseTime():Float { if (pauseStartTime == 0) return 0; - return Timer.stamp() - pauseStartTime; + return stamp() - pauseStartTime; + } + + function rateTime():Float { + if (rateStartTime == 0) return 0; + return stamp() - rateStartTime - pauseTime(); } } |
