aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRblSb <msrblsb@gmail.com>2020-06-07 18:45:22 +0300
committerRblSb <msrblsb@gmail.com>2020-06-07 18:45:22 +0300
commitd31f0b30481f6180e7907aee27413e5d208539aa (patch)
treead1281ef9f5100bd05108dc42b8f5107f585444a
parentf2567959538d7a7b26aa405353c2dbea4e6cc945 (diff)
Playlists "at next" order
-rw-r--r--res/client.js75
-rw-r--r--src/Types.hx5
-rw-r--r--src/client/IPlayer.hx3
-rw-r--r--src/client/Main.hx30
-rw-r--r--src/client/Player.hx11
-rw-r--r--src/client/players/Iframe.hx7
-rw-r--r--src/client/players/Raw.hx9
-rw-r--r--src/client/players/Youtube.hx32
8 files changed, 106 insertions, 66 deletions
diff --git a/res/client.js b/res/client.js
index 2c2a507..9bc4a2c 100644
--- a/res/client.js
+++ b/res/client.js
@@ -1080,17 +1080,23 @@ client_Main.prototype = {
var links = url.replace(_this_r,"|$1").split("|");
this.handleUrlMasks(links);
if(!atEnd) {
- var first = null;
- if(this.player.isListEmpty()) {
- first = links.shift();
- }
- links.reverse();
- if(this.player.isListEmpty()) {
- links.unshift(first);
- }
+ this.sortItemsForQueueNext(links);
}
this.addVideoArray(links,atEnd,isTemp);
}
+ ,sortItemsForQueueNext: function(items) {
+ if(items.length == 0) {
+ return;
+ }
+ var first = null;
+ if(this.player.isListEmpty()) {
+ first = items.shift();
+ }
+ items.reverse();
+ if(this.player.isListEmpty()) {
+ items.unshift(first);
+ }
+ }
,addVideoArray: function(links,atEnd,isTemp) {
var _gthis = this;
if(links.length == 0) {
@@ -1109,7 +1115,7 @@ client_Main.prototype = {
if(!StringTools.startsWith(url,"http")) {
url = "" + protocol + "//" + url;
}
- this.player.getVideoData(url,function(data) {
+ this.player.getVideoData({ url : url, atEnd : atEnd},function(data) {
if(data.duration == 0) {
_gthis.serverMessage(4,Lang.get("addVideoError"));
return;
@@ -1136,7 +1142,7 @@ client_Main.prototype = {
var title = mediaTitle.value;
mediaTitle.value = "";
var isTemp = window.document.querySelector("#customembed").querySelector(".add-temp").checked;
- this.player.getIframeData(iframe,function(data) {
+ this.player.getIframeData({ url : iframe, atEnd : atEnd},function(data) {
if(data.duration == 0) {
_gthis.serverMessage(4,Lang.get("addVideoError"));
return;
@@ -1184,7 +1190,7 @@ client_Main.prototype = {
var data = JSON.parse(e.data);
if(this.config != null && this.config.isVerbose) {
var t = data.type;
- haxe_Log.trace("Event: " + data.type,{ fileName : "src/client/Main.hx", lineNumber : 330, className : "client.Main", methodName : "onMessage", customParams : [Reflect.field(data,t.charAt(0).toLowerCase() + HxOverrides.substr(t,1,null))]});
+ haxe_Log.trace("Event: " + data.type,{ fileName : "src/client/Main.hx", lineNumber : 342, className : "client.Main", methodName : "onMessage", customParams : [Reflect.field(data,t.charAt(0).toLowerCase() + HxOverrides.substr(t,1,null))]});
}
client_JsApi.fireOnceEvent(data);
switch(data.type) {
@@ -1768,17 +1774,17 @@ client_Player.prototype = {
}
this.player = newPlayer;
}
- ,getVideoData: function(url,callback) {
+ ,getVideoData: function(data,callback) {
var player = Lambda.find(this.players,function(player) {
- return player.isSupportedLink(url);
+ return player.isSupportedLink(data.url);
});
if(player == null) {
player = this.rawPlayer;
}
- player.getVideoData(url,callback);
+ player.getVideoData(data,callback);
}
- ,getIframeData: function(iframe,callback) {
- this.iframePlayer.getVideoData(iframe,callback);
+ ,getIframeData: function(data,callback) {
+ this.iframePlayer.getVideoData(data,callback);
}
,setVideo: function(i) {
if(!this.main.isSyncActive) {
@@ -2227,7 +2233,7 @@ client_players_Iframe.prototype = {
}
,getVideoData: function(data,callback) {
var iframe = window.document.createElement("div");
- iframe.innerHTML = data;
+ iframe.innerHTML = data.url;
if(this.isValidIframe(iframe)) {
callback({ duration : 356400});
} else {
@@ -2296,8 +2302,9 @@ client_players_Raw.prototype = {
isSupportedLink: function(url) {
return true;
}
- ,getVideoData: function(url,callback) {
+ ,getVideoData: function(data,callback) {
var _gthis = this;
+ var url = data.url;
var decodedUrl = decodeURIComponent(url.split("+").join(" "));
var title = HxOverrides.substr(decodedUrl,decodedUrl.lastIndexOf("/") + 1,null);
var isNameMatched = this.matchName.match(title);
@@ -2311,7 +2318,7 @@ client_players_Raw.prototype = {
isHls = this.matchName.matched(2).indexOf("m3u8") != -1;
if(isHls && !this.isHlsLoaded) {
this.loadHlsPlugin(function() {
- _gthis.getVideoData(url,callback);
+ _gthis.getVideoData(data,callback);
});
return;
}
@@ -2509,19 +2516,20 @@ client_players_Youtube.prototype = {
}
return total;
}
- ,getVideoData: function(url,callback) {
+ ,getVideoData: function(data,callback) {
var _gthis = this;
+ var url = data.url;
if(this.apiKey == null) {
this.apiKey = this.main.getYoutubeApiKey();
}
var id = this.extractVideoId(url);
if(id == "") {
- this.getPlaylistVideoData(url,callback);
+ this.getPlaylistVideoData(data,callback);
return;
}
var http = new haxe_http_HttpJs("" + this.videosUrl + this.urlTitleDuration + "&id=" + id + "&key=" + this.apiKey);
- http.onData = function(data) {
- var json = JSON.parse(data);
+ http.onData = function(text) {
+ var json = JSON.parse(text);
if(json.error != null) {
_gthis.youtubeApiError(json.error);
_gthis.getRemoteDataFallback(url,callback);
@@ -2539,8 +2547,8 @@ client_players_Youtube.prototype = {
var title = item.snippet.title;
var duration = _gthis.convertTime(item.contentDetails.duration);
if(duration == 0) {
- callback({ duration : 356400, title : title, url : "<iframe src=\"https://www.youtube.com/embed/" + id + "\" frameborder=\"0\"\n\t\t\t\t\t\t\t\tallow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\"\n\t\t\t\t\t\t\t\tallowfullscreen></iframe>", isIframe : true});
- return;
+ callback({ duration : 356400, title : title, url : "<iframe src=\"https://www.youtube.com/embed/" + id + "\" frameborder=\"0\"\n\t\t\t\t\t\t\tallow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\"\n\t\t\t\t\t\t\tallowfullscreen></iframe>", isIframe : true});
+ continue;
}
callback({ duration : duration, title : title, url : url});
}
@@ -2550,12 +2558,12 @@ client_players_Youtube.prototype = {
};
http.request();
}
- ,getPlaylistVideoData: function(url,callback) {
+ ,getPlaylistVideoData: function(data,callback) {
var _gthis = this;
- var id = this.extractPlaylistId(url);
+ var id = this.extractPlaylistId(data.url);
var http = new haxe_http_HttpJs("" + this.playlistUrl + this.urlVideoId + "&maxResults=50&playlistId=" + id + "&key=" + this.apiKey);
- http.onData = function(data) {
- var json = JSON.parse(data);
+ http.onData = function(text) {
+ var json = JSON.parse(text);
if(json.error != null) {
_gthis.youtubeApiError(json.error);
callback({ duration : 0});
@@ -2566,10 +2574,13 @@ client_players_Youtube.prototype = {
callback({ duration : 0});
return;
}
+ if(!data.atEnd) {
+ _gthis.main.sortItemsForQueueNext(items);
+ }
var loadNextItem = null;
loadNextItem = function() {
- var id = items.shift().snippet.resourceId.videoId;
- _gthis.getVideoData("youtu.be/" + id,function(data) {
+ var obj = { url : "https://youtu.be/" + items.shift().snippet.resourceId.videoId, atEnd : data.atEnd};
+ _gthis.getVideoData(obj,function(data) {
callback(data);
if(items.length > 0) {
loadNextItem();
@@ -2603,7 +2614,7 @@ client_players_Youtube.prototype = {
}
callback({ duration : _gthis.tempYoutube.getDuration()});
}, onError : function(e) {
- haxe_Log.trace("Error " + e.data,{ fileName : "src/client/players/Youtube.hx", lineNumber : 183, className : "client.players.Youtube", methodName : "getRemoteDataFallback"});
+ haxe_Log.trace("Error " + e.data,{ fileName : "src/client/players/Youtube.hx", lineNumber : 191, className : "client.players.Youtube", methodName : "getRemoteDataFallback"});
if(_gthis.playerEl.contains(video)) {
_gthis.playerEl.removeChild(video);
}
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<String> = 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<T>(items:Array<T>):Void {
+ if (items.length == 0) return;
+ // except first item when list empty
+ var first:Null<T> = null;
+ if (player.isListEmpty()) first = items.shift();
+ items.reverse();
+ if (player.isListEmpty()) items.unshift(first);
+ }
+
function addVideoArray(links:Array<String>, 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: '<iframe src="https://www.youtube.com/embed/$id" frameborder="0"
- allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
- allowfullscreen></iframe>',
+ allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
+ allowfullscreen></iframe>',
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();
});
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage