From 104d4edeb5c0874412b0e91d0cb3c768995a0ce1 Mon Sep 17 00:00:00 2001 From: RblSb Date: Fri, 1 May 2020 10:11:40 +0300 Subject: Support youtube streams --- res/client.js | 62 ++++++++++++++++++++++++++++++++++--------- src/Types.hx | 3 ++- src/client/Main.hx | 40 +++++++++++++++++----------- src/client/Player.hx | 4 +++ src/client/players/Iframe.hx | 23 ++++++++++------ src/client/players/Youtube.hx | 16 +++++++++-- 6 files changed, 109 insertions(+), 39 deletions(-) diff --git a/res/client.js b/res/client.js index 949959d..a1fc8fb 100644 --- a/res/client.js +++ b/res/client.js @@ -1133,23 +1133,38 @@ client_Main.prototype = { if(data.url == null) { data.url = url; } - _gthis.send({ type : "AddVideo", addVideo : { item : { url : data.url, title : data.title, author : _gthis.personal.name, duration : data.duration, isTemp : isTemp, isIframe : false}, atEnd : atEnd}}); + _gthis.send({ type : "AddVideo", addVideo : { item : { url : data.url, title : data.title, author : _gthis.personal.name, duration : data.duration, isTemp : isTemp, isIframe : data.isIframe == true}, atEnd : atEnd}}); callback(); return; }); } ,addIframe: function(atEnd) { + var _gthis = this; var iframeCode = window.document.querySelector("#customembed-content"); var iframe = iframeCode.value; if(iframe.length == 0) { return; } iframeCode.value = ""; - var mediaName = window.document.querySelector("#customembed-title"); - var name = mediaName.value.length == 0 ? "Custom Media" : mediaName.value; - mediaName.value = ""; + var mediaTitle = window.document.querySelector("#customembed-title"); + var title = mediaTitle.value; + mediaTitle.value = ""; var isTemp = window.document.querySelector("#customembed").querySelector(".add-temp").checked; - this.send({ type : "AddVideo", addVideo : { item : { url : iframe, title : name, author : this.personal.name, duration : 356400, isTemp : isTemp, isIframe : true}, atEnd : atEnd}}); + this.player.getIframeData(iframe,function(data) { + if(data.duration == 0) { + var tmp = Lang.get("addVideoError"); + _gthis.serverMessage(4,tmp); + return; + } + if(title.length > 0) { + data.title = title; + } + if(data.url == null) { + data.url = iframe; + } + _gthis.send({ type : "AddVideo", addVideo : { item : { url : data.url, title : data.title, author : _gthis.personal.name, duration : data.duration, isTemp : isTemp, isIframe : true}, atEnd : atEnd}}); + return; + }); } ,toggleVideoElement: function() { if(this.player.hasVideo()) { @@ -1182,7 +1197,7 @@ client_Main.prototype = { var data = JSON.parse(e.data); var t = data.type; var t1 = t.charAt(0).toLowerCase() + HxOverrides.substr(t,1,null); - haxe_Log.trace("Event: " + data.type,{ fileName : "src/client/Main.hx", lineNumber : 305, className : "client.Main", methodName : "onMessage", customParams : [data[t1]]}); + haxe_Log.trace("Event: " + data.type,{ fileName : "src/client/Main.hx", lineNumber : 325, className : "client.Main", methodName : "onMessage", customParams : [data[t1]]}); switch(data.type) { case "AddVideo": this.player.addVideoItem(data.addVideo.item,data.addVideo.atEnd); @@ -1770,6 +1785,9 @@ client_Player.prototype = { } player.getVideoData(url,callback); } + ,getIframeData: function(iframe,callback) { + this.iframePlayer.getVideoData(iframe,callback); + } ,setVideo: function(i) { if(!this.main.isSyncActive) { return; @@ -2189,15 +2207,31 @@ client_players_Iframe.prototype = { isSupportedLink: function(url) { return true; } - ,getVideoData: function(url,callback) { - callback({ duration : 356400, title : "Custom Media"}); + ,getVideoData: function(data,callback) { + var iframe = window.document.createElement("div"); + iframe.innerHTML = data; + if(this.isValidIframe(iframe)) { + callback({ duration : 356400}); + } else { + callback({ duration : 0}); + } + } + ,isValidIframe: function(iframe) { + if(iframe.children.length != 1) { + return false; + } + if(iframe.firstChild.nodeName != "IFRAME") { + return iframe.firstChild.nodeName == "OBJECT"; + } else { + return true; + } } ,loadVideo: function(item) { this.removeVideo(); this.video = window.document.createElement("div"); this.video.id = "videoplayer"; this.video.innerHTML = item.url; - if(this.video.firstChild.nodeName != "IFRAME" && this.video.firstChild.nodeName != "OBJECT") { + if(!this.isValidIframe(this.video)) { this.video = null; return; } @@ -2441,8 +2475,12 @@ client_players_Youtube.prototype = { var item = items[_g]; ++_g; var title = item.snippet.title; - var tmp = _gthis.convertTime(item.contentDetails.duration); - callback({ duration : tmp, title : title, url : url}); + var duration = _gthis.convertTime(item.contentDetails.duration); + if(duration == 0) { + callback({ duration : 356400, title : title, url : "", isIframe : true}); + return; + } + callback({ duration : duration, title : title, url : url}); } return; }; @@ -2511,7 +2549,7 @@ client_players_Youtube.prototype = { callback({ duration : tmp}); return; }, onError : function(e1) { - haxe_Log.trace("Error " + e1.data,{ fileName : "src/client/players/Youtube.hx", lineNumber : 171, className : "client.players.Youtube", methodName : "getRemoteDataFallback"}); + haxe_Log.trace("Error " + e1.data,{ fileName : "src/client/players/Youtube.hx", lineNumber : 183, 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 366b2ed..ae13a6a 100644 --- a/src/Types.hx +++ b/src/Types.hx @@ -5,7 +5,8 @@ import Client.ClientData; typedef VideoData = { duration:Float, ?title:String, - ?url:String + ?url:String, + ?isIframe:Bool } typedef Config = { diff --git a/src/client/Main.hx b/src/client/Main.hx index 3400595..900f841 100644 --- a/src/client/Main.hx +++ b/src/client/Main.hx @@ -250,7 +250,7 @@ class Main { author: personal.name, duration: data.duration, isTemp: isTemp, - isIframe: false + isIframe: data.isIframe == true }, atEnd: atEnd }}); @@ -263,23 +263,31 @@ class Main { final iframe = iframeCode.value; if (iframe.length == 0) return; iframeCode.value = ""; - final mediaName:InputElement = cast ge("#customembed-title"); - final name = mediaName.value.length == 0 ? "Custom Media" : mediaName.value; - mediaName.value = ""; + final mediaTitle:InputElement = cast ge("#customembed-title"); + final title = mediaTitle.value; + mediaTitle.value = ""; final checkbox:InputElement = cast ge("#customembed").querySelector(".add-temp"); final isTemp = checkbox.checked; - send({ - type: AddVideo, addVideo: { - item: { - url: iframe, - title: name, - author: personal.name, - duration: 99 * 60 * 60, - isTemp: isTemp, - isIframe: true - }, - atEnd: atEnd - }}); + player.getIframeData(iframe, (data:VideoData) -> { + if (data.duration == 0) { + serverMessage(4, Lang.get("addVideoError")); + return; + } + if (title.length > 0) data.title = title; + if (data.url == null) data.url = iframe; + send({ + type: AddVideo, addVideo: { + item: { + url: data.url, + title: data.title, + author: personal.name, + duration: data.duration, + isTemp: isTemp, + isIframe: true + }, + atEnd: atEnd + }}); + }); } public function toggleVideoElement():Bool { diff --git a/src/client/Player.hx b/src/client/Player.hx index 28b5c09..5c283f7 100644 --- a/src/client/Player.hx +++ b/src/client/Player.hx @@ -101,6 +101,10 @@ class Player { player.getVideoData(url, callback); } + public function getIframeData(iframe:String, callback:(data:VideoData)->Void):Void { + iframePlayer.getVideoData(iframe, callback); + } + public function setVideo(i:Int):Void { if (!main.isSyncActive) return; final item = items[i]; diff --git a/src/client/players/Iframe.hx b/src/client/players/Iframe.hx index 3268a61..2f875fb 100644 --- a/src/client/players/Iframe.hx +++ b/src/client/players/Iframe.hx @@ -24,11 +24,20 @@ class Iframe implements IPlayer { return true; } - public function getVideoData(url:String, callback:(data:VideoData)->Void):Void { - callback({ - duration: 99 * 60 * 60, - title: "Custom Media" - }); + public function getVideoData(data:String, callback:(data:VideoData)->Void):Void { + final iframe = document.createDivElement(); + iframe.innerHTML = data; + if (isValidIframe(iframe)) { + callback({duration: 99 * 60 * 60}); + } else { + callback({duration: 0}); + } + } + + function isValidIframe(iframe:Element):Bool { + if (iframe.children.length != 1) return false; + return (iframe.firstChild.nodeName == "IFRAME" + || iframe.firstChild.nodeName == "OBJECT"); } public function loadVideo(item:VideoItem):Void { @@ -36,9 +45,7 @@ class Iframe implements IPlayer { video = document.createDivElement(); video.id = "videoplayer"; video.innerHTML = item.url; // actually data - if (video.firstChild.nodeName != "IFRAME" - && video.firstChild.nodeName != "OBJECT") { - // TODO move to getVideoData too + if (!isValidIframe(video)) { video = null; return; } diff --git a/src/client/players/Youtube.hx b/src/client/players/Youtube.hx index 0aa9f2b..f5f12a0 100644 --- a/src/client/players/Youtube.hx +++ b/src/client/players/Youtube.hx @@ -96,9 +96,21 @@ class Youtube implements IPlayer { for (item in items) { final title:String = item.snippet.title; final duration:String = item.contentDetails.duration; - // TODO duration is PT0S for streams + final duration = convertTime(duration); + // duration is PT0S for streams + if (duration == 0) { + callback({ + duration: 99 * 60 * 60, + title: title, + url: '', + isIframe: true + }); + return; + } callback({ - duration: convertTime(duration), + duration: duration, title: title, url: url }); -- cgit v1.2.3