diff options
Diffstat (limited to 'src/client')
| -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 |
5 files changed, 72 insertions, 40 deletions
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; } |
