From d31f0b30481f6180e7907aee27413e5d208539aa Mon Sep 17 00:00:00 2001 From: RblSb Date: Sun, 7 Jun 2020 18:45:22 +0300 Subject: Playlists "at next" order --- src/Types.hx | 5 +++++ src/client/IPlayer.hx | 3 ++- src/client/Main.hx | 30 +++++++++++++++++++++--------- src/client/Player.hx | 11 ++++++----- src/client/players/Iframe.hx | 7 +++---- src/client/players/Raw.hx | 9 ++++++--- src/client/players/Youtube.hx | 32 ++++++++++++++++++++------------ 7 files changed, 63 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/Types.hx b/src/Types.hx index eb137da..f9bc104 100644 --- a/src/Types.hx +++ b/src/Types.hx @@ -2,6 +2,11 @@ package; import Client.ClientData; +typedef VideoDataRequest = { + url:String, + atEnd:Bool +} + typedef VideoData = { duration:Float, ?title:String, diff --git a/src/client/IPlayer.hx b/src/client/IPlayer.hx index 4cdcb0b..7f626b1 100644 --- a/src/client/IPlayer.hx +++ b/src/client/IPlayer.hx @@ -1,11 +1,12 @@ package client; +import Types.VideoDataRequest; import Types.VideoData; import Types.VideoItem; interface IPlayer { function isSupportedLink(url:String):Bool; - function getVideoData(url:String, callback:(data:VideoData)->Void):Void; + function getVideoData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void; function loadVideo(item:VideoItem):Void; function removeVideo():Void; function isVideoLoaded():Bool; diff --git a/src/client/Main.hx b/src/client/Main.hx index 1cf4b04..c8750ca 100644 --- a/src/client/Main.hx +++ b/src/client/Main.hx @@ -14,6 +14,7 @@ import js.Browser; import js.Browser.document; import js.Browser.window; import Client.ClientData; +import Types.VideoDataRequest; import Types.VideoData; import Types.Config; import Types.WsEvent; @@ -213,16 +214,19 @@ class Main { final links = url.split("|"); handleUrlMasks(links); // if videos added as next, we need to load them in reverse order - if (!atEnd) { - // except first item when list empty - var first:Null = null; - if (player.isListEmpty()) first = links.shift(); - links.reverse(); - if (player.isListEmpty()) links.unshift(first); - } + if (!atEnd) sortItemsForQueueNext(links); addVideoArray(links, atEnd, isTemp); } + public function sortItemsForQueueNext(items:Array):Void { + if (items.length == 0) return; + // except first item when list empty + var first:Null = null; + if (player.isListEmpty()) first = items.shift(); + items.reverse(); + if (player.isListEmpty()) items.unshift(first); + } + function addVideoArray(links:Array, atEnd:Bool, isTemp:Bool):Void { if (links.length == 0) return; final link = links.shift(); @@ -238,7 +242,11 @@ class Main { } if (!url.startsWith("http")) url = '$protocol//$url'; - player.getVideoData(url, (data:VideoData) -> { + final obj:VideoDataRequest = { + url: url, + atEnd: atEnd + }; + player.getVideoData(obj, (data:VideoData) -> { if (data.duration == 0) { serverMessage(4, Lang.get("addVideoError")); return; @@ -271,7 +279,11 @@ class Main { mediaTitle.value = ""; final checkbox:InputElement = cast ge("#customembed").querySelector(".add-temp"); final isTemp = checkbox.checked; - player.getIframeData(iframe, (data:VideoData) -> { + final obj:VideoDataRequest = { + url: iframe, + atEnd: atEnd + }; + player.getIframeData(obj, (data:VideoData) -> { if (data.duration == 0) { serverMessage(4, Lang.get("addVideoError")); return; diff --git a/src/client/Player.hx b/src/client/Player.hx index dd49ab4..7de6d36 100644 --- a/src/client/Player.hx +++ b/src/client/Player.hx @@ -5,6 +5,7 @@ import client.Main.ge; import client.players.Raw; import client.players.Youtube; import client.players.Iframe; +import Types.VideoDataRequest; import Types.VideoData; import Types.VideoItem; using StringTools; @@ -97,14 +98,14 @@ class Player { player = newPlayer; } - public function getVideoData(url:String, callback:(data:VideoData)->Void):Void { - var player = players.find(player -> player.isSupportedLink(url)); + public function getVideoData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void { + var player = players.find(player -> player.isSupportedLink(data.url)); if (player == null) player = rawPlayer; - player.getVideoData(url, callback); + player.getVideoData(data, callback); } - public function getIframeData(iframe:String, callback:(data:VideoData)->Void):Void { - iframePlayer.getVideoData(iframe, callback); + public function getIframeData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void { + iframePlayer.getVideoData(data, callback); } public function setVideo(i:Int):Void { diff --git a/src/client/players/Iframe.hx b/src/client/players/Iframe.hx index 2f875fb..ae37c94 100644 --- a/src/client/players/Iframe.hx +++ b/src/client/players/Iframe.hx @@ -1,10 +1,9 @@ package client.players; -import haxe.Timer; import js.html.Element; -import js.html.VideoElement; import js.Browser.document; import client.Main.ge; +import Types.VideoDataRequest; import Types.VideoData; import Types.VideoItem; @@ -24,9 +23,9 @@ class Iframe implements IPlayer { return true; } - public function getVideoData(data:String, callback:(data:VideoData)->Void):Void { + public function getVideoData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void { final iframe = document.createDivElement(); - iframe.innerHTML = data; + iframe.innerHTML = data.url; if (isValidIframe(iframe)) { callback({duration: 99 * 60 * 60}); } else { diff --git a/src/client/players/Raw.hx b/src/client/players/Raw.hx index 57dd9b3..9a9d52e 100644 --- a/src/client/players/Raw.hx +++ b/src/client/players/Raw.hx @@ -6,6 +6,7 @@ import js.html.Element; import js.html.VideoElement; import js.Browser.document; import client.Main.ge; +import Types.VideoDataRequest; import Types.VideoData; import Types.VideoItem; using StringTools; @@ -30,7 +31,8 @@ class Raw implements IPlayer { return true; } - public function getVideoData(url:String, callback:(data:VideoData)->Void):Void { + public function getVideoData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void { + final url = data.url; final decodedUrl = url.urlDecode(); var title = decodedUrl.substr(decodedUrl.lastIndexOf("/") + 1); final isNameMatched = matchName.match(title); @@ -40,7 +42,7 @@ class Raw implements IPlayer { if (isNameMatched) { isHls = matchName.matched(2).contains("m3u8"); if (isHls && !isHlsLoaded) { - loadHlsPlugin(() -> getVideoData(url, callback)); + loadHlsPlugin(() -> getVideoData(data, callback)); return; } } @@ -63,7 +65,8 @@ class Raw implements IPlayer { } function loadHlsPlugin(callback:()->Void):Void { - JsApi.addScriptToHead("https://cdn.jsdelivr.net/npm/hls.js@latest", () -> { + final url = "https://cdn.jsdelivr.net/npm/hls.js@latest"; + JsApi.addScriptToHead(url, () -> { isHlsLoaded = true; callback(); }); diff --git a/src/client/players/Youtube.hx b/src/client/players/Youtube.hx index f5f12a0..45f74dd 100644 --- a/src/client/players/Youtube.hx +++ b/src/client/players/Youtube.hx @@ -7,6 +7,7 @@ import js.Browser.document; import client.Main.ge; import js.youtube.Youtube as YtInit; import js.youtube.YoutubePlayer; +import Types.VideoDataRequest; import Types.VideoData; import Types.VideoItem; using StringTools; @@ -72,17 +73,18 @@ class Youtube implements IPlayer { return total; } - public function getVideoData(url:String, callback:(data:VideoData)->Void):Void { + public function getVideoData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void { + final url = data.url; if (apiKey == null) apiKey = main.getYoutubeApiKey(); - var id = extractVideoId(url); + final id = extractVideoId(url); if (id == "") { - getPlaylistVideoData(url, callback); + getPlaylistVideoData(data, callback); return; } final dataUrl = '$videosUrl$urlTitleDuration&id=$id&key=$apiKey'; final http = new Http(dataUrl); - http.onData = data -> { - final json = Json.parse(data); + http.onData = text -> { + final json = Json.parse(text); if (json.error != null) { youtubeApiError(json.error); getRemoteDataFallback(url, callback); @@ -103,11 +105,11 @@ class Youtube implements IPlayer { duration: 99 * 60 * 60, title: title, url: '', + allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" + allowfullscreen>', isIframe: true }); - return; + continue; } callback({ duration: duration, @@ -120,12 +122,13 @@ class Youtube implements IPlayer { http.request(); } - function getPlaylistVideoData(url:String, callback:(data:VideoData)->Void):Void { + function getPlaylistVideoData(data:VideoDataRequest, callback:(data:VideoData)->Void):Void { + final url = data.url; final id = extractPlaylistId(url); final dataUrl = '$playlistUrl$urlVideoId&maxResults=50&playlistId=$id&key=$apiKey'; final http = new Http(dataUrl); - http.onData = data -> { - final json = Json.parse(data); + http.onData = text -> { + final json = Json.parse(text); if (json.error != null) { youtubeApiError(json.error); callback({duration: 0}); @@ -136,10 +139,15 @@ class Youtube implements IPlayer { callback({duration: 0}); return; } + if (!data.atEnd) main.sortItemsForQueueNext(items); function loadNextItem():Void { final item = items.shift(); final id:String = item.snippet.resourceId.videoId; - getVideoData('youtu.be/$id', data -> { + final obj = { + url: 'https://youtu.be/$id', + atEnd: data.atEnd + }; + getVideoData(obj, data -> { callback(data); if (items.length > 0) loadNextItem(); }); -- cgit v1.2.3