diff options
| author | RblSb <msrblsb@gmail.com> | 2024-04-29 07:45:10 +0300 |
|---|---|---|
| committer | RblSb <msrblsb@gmail.com> | 2024-04-29 07:45:10 +0300 |
| commit | 5d2375cbb23dbe69a7afe7a691707be48397c6d9 (patch) | |
| tree | 2fe92ab48e83427b3a7e90855545f73c2c8daa3e /src | |
| parent | 9d844bbf3ac6be327325b13a91a6b33f73c49c1d (diff) | |
Video item fixes
- Fix youtube fallback, `videoItem.url` is now immutable
- JsApi.setVideoSrc now updates to supported player based on `url` arg
- Fix auto-pause when video is ended (with `requestLeaderOnPause`)
Diffstat (limited to 'src')
| -rw-r--r-- | src/Types.hx | 30 | ||||
| -rw-r--r-- | src/VideoList.hx | 4 | ||||
| -rw-r--r-- | src/client/JsApi.hx | 4 | ||||
| -rw-r--r-- | src/client/Player.hx | 37 | ||||
| -rw-r--r-- | src/client/players/Youtube.hx | 5 | ||||
| -rw-r--r-- | src/server/Main.hx | 10 |
6 files changed, 55 insertions, 35 deletions
diff --git a/src/Types.hx b/src/Types.hx index eeae641..27b2cce 100644 --- a/src/Types.hx +++ b/src/Types.hx @@ -98,14 +98,30 @@ typedef Message = { time:String } +@:using(Types.VideoItemTools) typedef VideoItem = { - url:String, - title:String, - author:String, - duration:Float, - ?subs:String, - isTemp:Bool, - isIframe:Bool + /** Immutable, used as identifier for skipping / removing items **/ + final url:String; + var title:String; + var author:String; + var duration:Float; + var ?subs:String; + var isTemp:Bool; + var isIframe:Bool; +} + +private class VideoItemTools { + public static function withUrl(item:VideoItem, url:String):VideoItem { + return { + url: url, + title: item.title, + author: item.author, + duration: item.duration, + subs: item.subs, + isTemp: item.isTemp, + isIframe: item.isIframe + }; + } } typedef FlashbackItem = { diff --git a/src/VideoList.hx b/src/VideoList.hx index 094d2ab..b677060 100644 --- a/src/VideoList.hx +++ b/src/VideoList.hx @@ -17,13 +17,13 @@ class VideoList { return items.length; } - public var currentItem(get, never):VideoItem; + public var currentItem(get, never):Null<VideoItem>; inline function get_currentItem():Null<VideoItem> { return items[pos]; } - public inline function getItem(i:Int):VideoItem { + public inline function getItem(i:Int):Null<VideoItem> { return items[i]; } diff --git a/src/client/JsApi.hx b/src/client/JsApi.hx index 637878d..09e6edb 100644 --- a/src/client/JsApi.hx +++ b/src/client/JsApi.hx @@ -104,8 +104,8 @@ class JsApi { } @:expose - public static function setVideoSrc(src:String):Void { - player.changeVideoSrc(src); + public static function setVideoSrc(url:String):Void { + player.changeVideoSrc(url); } /** Returns current page hostname (domain without protocol) **/ diff --git a/src/client/Player.hx b/src/client/Player.hx index 06a8f3e..c250a34 100644 --- a/src/client/Player.hx +++ b/src/client/Player.hx @@ -89,7 +89,7 @@ class Player { setItemElementType(el, videoList.getItem(pos).isTemp); } - public function getCurrentItem():VideoItem { + public function getCurrentItem():Null<VideoItem> { return videoList.currentItem; } @@ -121,10 +121,7 @@ class Player { public function setVideo(i:Int):Void { if (!main.isSyncActive) return; final item = videoList.getItem(i); - var currentPlayer = players.find(p -> p.isSupportedLink(item.url)); - if (currentPlayer != null) setPlayer(currentPlayer); - else if (item.isIframe) setPlayer(iframePlayer); - else setPlayer(rawPlayer); + setSupportedPlayer(item.url, item.isIframe); removeActiveLabel(videoList.pos); videoList.setPos(i); @@ -140,19 +137,18 @@ class Player { ge("#currenttitle").textContent = item.title; } - public function changeVideoSrc(src:String):Void { + function setSupportedPlayer(url:String, isIframe:Bool):Void { + final currentPlayer = players.find(p -> p.isSupportedLink(url)); + if (currentPlayer != null) setPlayer(currentPlayer); + else if (isIframe) setPlayer(iframePlayer); + else setPlayer(rawPlayer); + } + + public function changeVideoSrc(url:String):Void { if (!main.isVideoEnabled) return; - if (player == null) return; - final item = videoList.currentItem ?? return; - player.loadVideo({ - url: src, - title: item.title, - author: item.author, - duration: item.duration, - subs: item.subs, - isTemp: item.isTemp, - isIframe: item.isIframe - }); + final item:VideoItem = videoList.currentItem ?? return; + setSupportedPlayer(url, item.isIframe); + player.loadVideo(item.withUrl(url)); } public function removeVideo():Void { @@ -191,6 +187,13 @@ class Player { } public function onPause():Void { + final item = videoList.currentItem ?? return; + // do not send pause if video is ended + if (getTime() >= item.duration - 0.01) return; + // youtube raw fallback has around one second difference from rounded youtube duration + if (player == rawPlayer && youtube.isSupportedLink(item.url)) { + if (getTime() >= item.duration - 1) return; + } final hasAutoPause = main.hasLeaderOnPauseRequest() && videoList.length > 0 && getTime() > 1; if (hasAutoPause && !main.hasLeader()) { diff --git a/src/client/players/Youtube.hx b/src/client/players/Youtube.hx index 5308b63..7c98b3f 100644 --- a/src/client/players/Youtube.hx +++ b/src/client/players/Youtube.hx @@ -243,6 +243,7 @@ class Youtube implements IPlayer { onError: e -> { // TODO message error codes trace('Error ${e.data}'); + final item = player.getCurrentItem() ?? return; rawSourceFallback(item.url); } } @@ -258,9 +259,7 @@ class Youtube implements IPlayer { trace(info); return; }; - final item = player.getCurrentItem(); - item.url = format.url; - player.refresh(); + player.changeVideoSrc(format.url); }); main.send({ type: GetYoutubeVideoInfo, diff --git a/src/server/Main.hx b/src/server/Main.hx index e7c38a6..4f09108 100644 --- a/src/server/Main.hx +++ b/src/server/Main.hx @@ -612,16 +612,18 @@ class Main { if (!data.addVideo.atEnd && !checkPermission(client, ChangeOrderPerm)) { data.addVideo.atEnd = true; } - final item = data.addVideo.item; + var item = data.addVideo.item; item.author = client.name; - final local = '$localIp:$port'; - if (item.url.contains(local)) { - item.url = item.url.replace(local, '$globalIp:$port'); + final localIpPort = '$localIp:$port'; + if (item.url.contains(localIpPort)) { + final newUrl = item.url.replace(localIpPort, '$globalIp:$port'); + item = item.withUrl(newUrl); } if (videoList.exists(i -> i.url == item.url)) { serverMessage(client, "videoAlreadyExistsError"); return; } + data.addVideo.item = item; videoList.addItem(item, data.addVideo.atEnd); broadcast(data); // Initial timer start if VideoLoaded is not happen |
