diff options
| author | RblSb <msrblsb@gmail.com> | 2020-04-23 22:48:37 +0300 |
|---|---|---|
| committer | RblSb <msrblsb@gmail.com> | 2020-04-24 05:29:48 +0300 |
| commit | 177057877733c33aadbb11b5884fe2c4a3e13de5 (patch) | |
| tree | 50035a705fa21f333f66485fe724d5c52e7fc5d5 | |
| parent | 3e1f20569d467160dfe578bd80393a528dc60db7 (diff) | |
Fix youtube bg autoplay
| -rw-r--r-- | res/client.js | 176 | ||||
| -rw-r--r-- | src/client/IPlayer.hx | 1 | ||||
| -rw-r--r-- | src/client/Player.hx | 38 | ||||
| -rw-r--r-- | src/client/players/Iframe.hx | 5 | ||||
| -rw-r--r-- | src/client/players/Raw.hx | 17 | ||||
| -rw-r--r-- | src/client/players/Youtube.hx | 51 |
6 files changed, 184 insertions, 104 deletions
diff --git a/res/client.js b/res/client.js index 9637f8a..c0a61e3 100644 --- a/res/client.js +++ b/res/client.js @@ -126,6 +126,16 @@ Lambda.exists = function(it,f) { } return false; }; +Lambda.find = function(it,f) { + var v = $getIterator(it); + while(v.hasNext()) { + var v1 = v.next(); + if(f(v1)) { + return v1; + } + } + return null; +}; var haxe_ds_StringMap = function() { this.h = { }; }; @@ -1598,6 +1608,9 @@ var client_Player = function(main) { this.videoItemsEl = window.document.querySelector("#queue"); this.items = _$VideoList_VideoList_$Impl_$._new(); this.main = main; + this.players = [new client_players_Youtube(main,this)]; + this.iframePlayer = new client_players_Iframe(main,this); + this.rawPlayer = new client_players_Raw(main,this); this.initItemButtons(); }; client_Player.__name__ = true; @@ -1633,27 +1646,35 @@ client_Player.prototype = { _$VideoList_VideoList_$Impl_$.toggleItemType(this.items,pos); this.setItemElementType(this.videoItemsEl.children[pos],this.items[pos].isTemp); } - ,setPlayer: function(player) { - this.player = player; + ,setPlayer: function(newPlayer) { + if(this.player != null && this.player != newPlayer) { + this.player.removeVideo(); + } + this.player = newPlayer; } ,getVideoData: function(url,callback) { - if(client_players_Youtube.isYoutube(url)) { - new client_players_Youtube(this.main,this).getVideoData(url,callback); - } else { - new client_players_Raw(this.main,this).getVideoData(url,callback); + var player = Lambda.find(this.players,function(player1) { + return player1.isSupportedLink(url); + }); + if(player == null) { + player = this.rawPlayer; } + player.getVideoData(url,callback); } ,setVideo: function(i) { if(!this.main.isSyncActive) { return; } var item = this.items[i]; - if(item.isIframe) { - this.setPlayer(new client_players_Iframe(this.main,this)); - } else if(client_players_Youtube.isYoutube(item.url)) { - this.setPlayer(new client_players_Youtube(this.main,this)); + var currentPlayer = Lambda.find(this.players,function(p) { + return p.isSupportedLink(item.url); + }); + if(currentPlayer != null) { + this.setPlayer(currentPlayer); + } else if(item.isIframe) { + this.setPlayer(this.iframePlayer); } else { - this.setPlayer(new client_players_Raw(this.main,this)); + this.setPlayer(this.rawPlayer); } var childs = this.videoItemsEl.children; if(childs[this.itemPos] != null) { @@ -1662,7 +1683,6 @@ client_Player.prototype = { this.itemPos = i; childs[this.itemPos].classList.add("queue_active"); this.currentSrc = item.url; - this.playerEl.textContent = ""; this.isLoaded = false; this.player.loadVideo(item); window.document.querySelector("#currenttitle").textContent = item.title; @@ -2038,7 +2058,14 @@ var client_players_Iframe = function(main,player) { }; client_players_Iframe.__name__ = true; client_players_Iframe.prototype = { - loadVideo: function(item) { + isSupportedLink: function(url) { + return true; + } + ,getVideoData: function(url,callback) { + callback({ duration : 356400, title : "Custom Media"}); + } + ,loadVideo: function(item) { + this.removeVideo(); this.video = window.document.createElement("div"); this.video.id = "videoplayer"; this.video.innerHTML = item.url; @@ -2081,7 +2108,10 @@ var client_players_Raw = function(main,player) { }; client_players_Raw.__name__ = true; client_players_Raw.prototype = { - getVideoData: function(url,callback) { + isSupportedLink: function(url) { + return true; + } + ,getVideoData: function(url,callback) { var _gthis = this; var title = HxOverrides.substr(url,url.lastIndexOf("/") + 1,null); var matchName = new EReg("^(.+)\\.",""); @@ -2110,22 +2140,27 @@ client_players_Raw.prototype = { } ,loadVideo: function(item) { var _gthis = this; + var url = this.main.tryLocalIp(item.url); + if(this.video != null) { + this.video.src = url; + return; + } this.video = window.document.createElement("video"); this.video.id = "videoplayer"; - var url = this.main.tryLocalIp(item.url); this.video.src = url; this.video.controls = true; - var isTouch = 'ontouchstart' in window; - if(client_players_Raw.controlsHider != null) { - client_players_Raw.controlsHider.stop(); + if(this.controlsHider != null) { + this.controlsHider.stop(); } - if(!isTouch) { - client_players_Raw.controlsHider = haxe_Timer.delay(function() { + if(!client_Utils.isTouch()) { + this.controlsHider = haxe_Timer.delay(function() { return _gthis.video.controls = false; },3000); } this.video.onmousemove = function(e) { - client_players_Raw.controlsHider.stop(); + if(_gthis.controlsHider != null) { + _gthis.controlsHider.stop(); + } _gthis.video.controls = true; return _gthis.video.onmousemove = null; }; @@ -2200,40 +2235,47 @@ var client_players_Youtube = function(main,player) { this.matchHours = new EReg("([0-9]+)H",""); this.isLoaded = false; this.playerEl = window.document.querySelector("#ytapiplayer"); + this.urlVideoId = "?part=snippet&fields=items(snippet/resourceId/videoId)"; + this.urlTitleDuration = "?part=snippet,contentDetails&fields=items(snippet/title,contentDetails/duration)"; + this.playlistUrl = "https://www.googleapis.com/youtube/v3/playlistItems"; + this.videosUrl = "https://www.googleapis.com/youtube/v3/videos"; + this.matchPlaylist = new EReg("youtube\\.com.*list=([A-z0-9_-]+)",""); + this.matchEmbed = new EReg("embed/([A-z0-9_-]+)",""); + this.matchShort = new EReg("youtu.be/([A-z0-9_-]+)",""); + this.matchId = new EReg("v=([A-z0-9_-]+)",""); this.main = main; this.player = player; - client_players_Youtube.apiKey = main.getYoutubeApiKey(); }; client_players_Youtube.__name__ = true; -client_players_Youtube.isYoutube = function(url) { - if(client_players_Youtube.extractVideoId(url) == "") { - return client_players_Youtube.extractPlaylistId(url) != ""; - } else { - return true; - } -}; -client_players_Youtube.extractVideoId = function(url) { - if(url.indexOf("youtu.be/") != -1) { - client_players_Youtube.matchShort.match(url); - return client_players_Youtube.matchShort.matched(1); - } - if(url.indexOf("youtube.com/embed/") != -1) { - client_players_Youtube.matchEmbed.match(url); - return client_players_Youtube.matchEmbed.matched(1); +client_players_Youtube.prototype = { + isSupportedLink: function(url) { + if(this.extractVideoId(url) == "") { + return this.extractPlaylistId(url) != ""; + } else { + return true; + } } - if(!client_players_Youtube.matchId.match(url)) { - return ""; + ,extractVideoId: function(url) { + if(url.indexOf("youtu.be/") != -1) { + this.matchShort.match(url); + return this.matchShort.matched(1); + } + if(url.indexOf("youtube.com/embed/") != -1) { + this.matchEmbed.match(url); + return this.matchEmbed.matched(1); + } + if(!this.matchId.match(url)) { + return ""; + } + return this.matchId.matched(1); } - return client_players_Youtube.matchId.matched(1); -}; -client_players_Youtube.extractPlaylistId = function(url) { - if(!client_players_Youtube.matchPlaylist.match(url)) { - return ""; + ,extractPlaylistId: function(url) { + if(!this.matchPlaylist.match(url)) { + return ""; + } + return this.matchPlaylist.matched(1); } - return client_players_Youtube.matchPlaylist.matched(1); -}; -client_players_Youtube.prototype = { - convertTime: function(duration) { + ,convertTime: function(duration) { var total = 0; var hours = this.matchHours.match(duration); var minutes = this.matchMinutes.match(duration); @@ -2251,12 +2293,15 @@ client_players_Youtube.prototype = { } ,getVideoData: function(url,callback) { var _gthis = this; - var id = client_players_Youtube.extractVideoId(url); + if(this.apiKey == null) { + this.apiKey = this.main.getYoutubeApiKey(); + } + var id = this.extractVideoId(url); if(id == "") { this.getPlaylistVideoData(url,callback); return; } - var http = new haxe_http_HttpJs("" + client_players_Youtube.videosUrl + client_players_Youtube.urlTitleDuration + "&id=" + id + "&key=" + client_players_Youtube.apiKey); + var http = new haxe_http_HttpJs("" + this.videosUrl + this.urlTitleDuration + "&id=" + id + "&key=" + this.apiKey); http.onData = function(data) { var json = JSON.parse(data); if(json.error != null) { @@ -2287,7 +2332,8 @@ client_players_Youtube.prototype = { } ,getPlaylistVideoData: function(url,callback) { var _gthis = this; - var http = new haxe_http_HttpJs("" + client_players_Youtube.playlistUrl + client_players_Youtube.urlVideoId + "&maxResults=50&playlistId=" + client_players_Youtube.extractPlaylistId(url) + "&key=" + client_players_Youtube.apiKey); + var id = this.extractPlaylistId(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); if(json.error != null) { @@ -2335,15 +2381,15 @@ client_players_Youtube.prototype = { var video = window.document.createElement("div"); video.id = "temp-videoplayer"; client_Utils.prepend(this.playerEl,video); - this.youtube = new YT.Player(video.id,{ videoId : client_players_Youtube.extractVideoId(url), playerVars : { modestbranding : 1, rel : 0, showinfo : 0}, events : { onReady : function(e) { + this.tempYoutube = new YT.Player(video.id,{ videoId : this.extractVideoId(url), playerVars : { modestbranding : 1, rel : 0, showinfo : 0}, events : { onReady : function(e) { if(_gthis.playerEl.contains(video)) { _gthis.playerEl.removeChild(video); } - var tmp = _gthis.youtube.getDuration(); + var tmp = _gthis.tempYoutube.getDuration(); callback({ duration : tmp}); return; }, onError : function(e1) { - haxe_Log.trace("Error " + e1.data,{ fileName : "src/client/players/Youtube.hx", lineNumber : 170, className : "client.players.Youtube", methodName : "getRemoteDataFallback"}); + haxe_Log.trace("Error " + e1.data,{ fileName : "src/client/players/Youtube.hx", lineNumber : 171, className : "client.players.Youtube", methodName : "getRemoteDataFallback"}); if(_gthis.playerEl.contains(video)) { _gthis.playerEl.removeChild(video); } @@ -2360,11 +2406,18 @@ client_players_Youtube.prototype = { }); return; } + if(this.youtube != null) { + this.youtube.loadVideoById({ videoId : this.extractVideoId(item.url)}); + return; + } + this.isLoaded = false; this.video = window.document.createElement("div"); this.video.id = "videoplayer"; this.playerEl.appendChild(this.video); - this.youtube = new YT.Player(this.video.id,{ videoId : client_players_Youtube.extractVideoId(item.url), playerVars : { autoplay : 1, modestbranding : 1, rel : 0, showinfo : 0, start : 0}, events : { onReady : function(e) { - return _gthis.isLoaded = true; + this.youtube = new YT.Player(this.video.id,{ videoId : this.extractVideoId(item.url), playerVars : { autoplay : 1, modestbranding : 1, rel : 0, showinfo : 0}, events : { onReady : function(e) { + _gthis.isLoaded = true; + _gthis.youtube.pauseVideo(); + return; }, onStateChange : function(e1) { switch(e1.data) { case -1: @@ -2394,6 +2447,9 @@ client_players_Youtube.prototype = { if(this.video == null) { return; } + this.isLoaded = false; + this.youtube.destroy(); + this.youtube = null; if(this.playerEl.contains(this.video)) { this.playerEl.removeChild(this.video); } @@ -3080,14 +3136,6 @@ Lang.langs = new haxe_ds_StringMap(); Lang.ids = ["en","ru"]; Lang.lang = HxOverrides.substr(window.navigator.language,0,2).toLowerCase(); client_Settings.isSupported = false; -client_players_Youtube.matchId = new EReg("v=([A-z0-9_-]+)",""); -client_players_Youtube.matchShort = new EReg("youtu.be/([A-z0-9_-]+)",""); -client_players_Youtube.matchEmbed = new EReg("embed/([A-z0-9_-]+)",""); -client_players_Youtube.matchPlaylist = new EReg("youtube\\.com.*list=([A-z0-9_-]+)",""); -client_players_Youtube.videosUrl = "https://www.googleapis.com/youtube/v3/videos"; -client_players_Youtube.playlistUrl = "https://www.googleapis.com/youtube/v3/playlistItems"; -client_players_Youtube.urlTitleDuration = "?part=snippet,contentDetails&fields=items(snippet/title,contentDetails/duration)"; -client_players_Youtube.urlVideoId = "?part=snippet&fields=items(snippet/resourceId/videoId)"; js_youtube_Youtube.isLoadedAPI = false; client_Main.main(); })(typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : this); diff --git a/src/client/IPlayer.hx b/src/client/IPlayer.hx index e414af5..a620567 100644 --- a/src/client/IPlayer.hx +++ b/src/client/IPlayer.hx @@ -4,6 +4,7 @@ import Types.VideoData; import Types.VideoItem; interface IPlayer { + function isSupportedLink(url:String):Bool; function getVideoData(url:String, callback:(data:VideoData)->Void):Void; function loadVideo(item:VideoItem):Void; function removeVideo():Void; diff --git a/src/client/Player.hx b/src/client/Player.hx index 8979db8..92cee1c 100644 --- a/src/client/Player.hx +++ b/src/client/Player.hx @@ -9,10 +9,14 @@ import client.players.Iframe; import Types.VideoData; import Types.VideoItem; using StringTools; +using Lambda; class Player { final main:Main; + final players:Array<IPlayer>; + final iframePlayer:IPlayer; + final rawPlayer:IPlayer; final items = new VideoList(); final videoItemsEl = ge("#queue"); final playerEl:Element = ge("#ytapiplayer"); @@ -25,6 +29,11 @@ class Player { public function new(main:Main):Void { this.main = main; + players = [ + new Youtube(main, this) + ]; + iframePlayer = new Iframe(main, this); + rawPlayer = new Raw(main, this); initItemButtons(); } @@ -79,29 +88,27 @@ class Player { setItemElementType(el, items[pos].isTemp); } - function setPlayer(player:IPlayer):Void { - this.player = player; + function setPlayer(newPlayer:IPlayer):Void { + if (player != null && player != newPlayer) { + player.removeVideo(); + // playerEl.textContent = ""; + } + player = newPlayer; } public function getVideoData(url:String, callback:(data:VideoData)->Void):Void { - // TODO P2 reuse player objects - if (Youtube.isYoutube(url)) { - new Youtube(main, this).getVideoData(url, callback); - } else { - new Raw(main, this).getVideoData(url, callback); - } + var player = players.find(player -> player.isSupportedLink(url)); + if (player == null) player = rawPlayer; + player.getVideoData(url, callback); } public function setVideo(i:Int):Void { if (!main.isSyncActive) return; final item = items[i]; - if (item.isIframe) { - setPlayer(new Iframe(main, this)); - } else if (Youtube.isYoutube(item.url)) { - setPlayer(new Youtube(main, this)); - } else { - setPlayer(new Raw(main, this)); - } + var currentPlayer = players.find(p -> p.isSupportedLink(item.url)); + if (currentPlayer != null) setPlayer(currentPlayer); + else if (item.isIframe) setPlayer(iframePlayer); + else setPlayer(rawPlayer); final childs = videoItemsEl.children; if (childs[itemPos] != null) { @@ -111,7 +118,6 @@ class Player { childs[itemPos].classList.add("queue_active"); currentSrc = item.url; - playerEl.textContent = ""; isLoaded = false; player.loadVideo(item); ge("#currenttitle").textContent = item.title; diff --git a/src/client/players/Iframe.hx b/src/client/players/Iframe.hx index d79196b..1bb9855 100644 --- a/src/client/players/Iframe.hx +++ b/src/client/players/Iframe.hx @@ -20,6 +20,10 @@ class Iframe implements IPlayer { this.player = player; } + public function isSupportedLink(url:String):Bool { + return true; + } + public function getVideoData(url:String, callback:(data:VideoData)->Void):Void { callback({ duration: 99 * 60 * 60, @@ -28,6 +32,7 @@ class Iframe implements IPlayer { } public function loadVideo(item:VideoItem):Void { + removeVideo(); video = document.createDivElement(); video.id = "videoplayer"; video.innerHTML = item.url; diff --git a/src/client/players/Raw.hx b/src/client/players/Raw.hx index c3c96d4..e3c2ed1 100644 --- a/src/client/players/Raw.hx +++ b/src/client/players/Raw.hx @@ -10,10 +10,10 @@ import Types.VideoItem; class Raw implements IPlayer { - static var controlsHider:Timer; final main:Main; final player:Player; final playerEl:Element = ge("#ytapiplayer"); + var controlsHider:Timer; var playAllowed = true; var video:VideoElement; @@ -22,6 +22,10 @@ class Raw implements IPlayer { this.player = player; } + public function isSupportedLink(url:String):Bool { + return true; + } + public function getVideoData(url:String, callback:(data:VideoData)->Void):Void { var title = url.substr(url.lastIndexOf('/') + 1); final matchName = ~/^(.+)\./; @@ -45,18 +49,21 @@ class Raw implements IPlayer { } public function loadVideo(item:VideoItem):Void { + final url = main.tryLocalIp(item.url); + if (video != null) { + video.src = url; + return; + } video = document.createVideoElement(); video.id = "videoplayer"; - final url = main.tryLocalIp(item.url); video.src = url; video.controls = true; - final isTouch = untyped __js__("'ontouchstart' in window"); if (controlsHider != null) controlsHider.stop(); - if (!isTouch) controlsHider = Timer.delay(() -> { + if (!Utils.isTouch()) controlsHider = Timer.delay(() -> { video.controls = false; }, 3000); video.onmousemove = e -> { - controlsHider.stop(); + if (controlsHider != null) controlsHider.stop(); video.controls = true; video.onmousemove = null; } diff --git a/src/client/players/Youtube.hx b/src/client/players/Youtube.hx index cc4269d..3ea0e72 100644 --- a/src/client/players/Youtube.hx +++ b/src/client/players/Youtube.hx @@ -13,33 +13,33 @@ using StringTools; class Youtube implements IPlayer { - static final matchId = ~/v=([A-z0-9_-]+)/; - static final matchShort = ~/youtu.be\/([A-z0-9_-]+)/; - static final matchEmbed = ~/embed\/([A-z0-9_-]+)/; - static final matchPlaylist = ~/youtube\.com.*list=([A-z0-9_-]+)/; - static final videosUrl = "https://www.googleapis.com/youtube/v3/videos"; - static final playlistUrl = "https://www.googleapis.com/youtube/v3/playlistItems"; - static final urlTitleDuration = "?part=snippet,contentDetails&fields=items(snippet/title,contentDetails/duration)"; - static final urlVideoId = "?part=snippet&fields=items(snippet/resourceId/videoId)"; - static var apiKey:String; + final matchId = ~/v=([A-z0-9_-]+)/; + final matchShort = ~/youtu.be\/([A-z0-9_-]+)/; + final matchEmbed = ~/embed\/([A-z0-9_-]+)/; + final matchPlaylist = ~/youtube\.com.*list=([A-z0-9_-]+)/; + final videosUrl = "https://www.googleapis.com/youtube/v3/videos"; + final playlistUrl = "https://www.googleapis.com/youtube/v3/playlistItems"; + final urlTitleDuration = "?part=snippet,contentDetails&fields=items(snippet/title,contentDetails/duration)"; + final urlVideoId = "?part=snippet&fields=items(snippet/resourceId/videoId)"; final main:Main; final player:Player; final playerEl:Element = ge("#ytapiplayer"); + var apiKey:String; var video:Element; var youtube:YoutubePlayer; + var tempYoutube:YoutubePlayer; var isLoaded = false; public function new(main:Main, player:Player) { this.main = main; this.player = player; - apiKey = main.getYoutubeApiKey(); } - public static function isYoutube(url:String):Bool { + public function isSupportedLink(url:String):Bool { return extractVideoId(url) != "" || extractPlaylistId(url) != ""; } - static function extractVideoId(url:String):String { + function extractVideoId(url:String):String { if (url.contains("youtu.be/")) { matchShort.match(url); return matchShort.matched(1); @@ -52,7 +52,7 @@ class Youtube implements IPlayer { return matchId.matched(1); } - static function extractPlaylistId(url:String):String { + function extractPlaylistId(url:String):String { if (!matchPlaylist.match(url)) return ""; return matchPlaylist.matched(1); } @@ -73,6 +73,7 @@ class Youtube implements IPlayer { } public function getVideoData(url:String, callback:(data:VideoData)->Void):Void { + if (apiKey == null) apiKey = main.getYoutubeApiKey(); var id = extractVideoId(url); if (id == "") { getPlaylistVideoData(url, callback); @@ -151,7 +152,7 @@ class Youtube implements IPlayer { final video = document.createDivElement(); video.id = "temp-videoplayer"; Utils.prepend(playerEl, video); - youtube = new YoutubePlayer(video.id, { + tempYoutube = new YoutubePlayer(video.id, { videoId: extractVideoId(url), playerVars: { modestbranding: 1, @@ -162,7 +163,7 @@ class Youtube implements IPlayer { onReady: e -> { if (playerEl.contains(video)) playerEl.removeChild(video); callback({ - duration: youtube.getDuration() + duration: tempYoutube.getDuration() }); }, onError: e -> { @@ -180,6 +181,13 @@ class Youtube implements IPlayer { YtInit.init(() -> loadVideo(item)); return; } + if (youtube != null) { + youtube.loadVideoById({ + videoId: extractVideoId(item.url) + }); + return; + } + isLoaded = false; video = document.createDivElement(); video.id = "videoplayer"; playerEl.appendChild(video); @@ -190,11 +198,13 @@ class Youtube implements IPlayer { autoplay: 1, modestbranding: 1, rel: 0, - showinfo: 0, - start: 0 + showinfo: 0 }, events: { - onReady: e -> isLoaded = true, + onReady: e -> { + isLoaded = true; + youtube.pauseVideo(); + }, onStateChange: e -> { switch (e.data) { case UNSTARTED: @@ -211,13 +221,16 @@ class Youtube implements IPlayer { }, onPlaybackRateChange: e -> { player.onRateChange(); - }, + } } }); } public function removeVideo():Void { if (video == null) return; + isLoaded = false; + youtube.destroy(); + youtube = null; if (playerEl.contains(video)) playerEl.removeChild(video); video = null; } |
