aboutsummaryrefslogtreecommitdiffstats
path: root/src/client/players
diff options
context:
space:
mode:
authorRblSb <msrblsb@gmail.com>2020-02-28 19:55:32 +0300
committerRblSb <msrblsb@gmail.com>2020-02-28 19:55:32 +0300
commitec7e4b5ad120828f1464cf4186287d4928b462a8 (patch)
tree6ea0accbe62983f3f174df9bf9ebc89bec17977a /src/client/players
parentc5903d5670dad72c840c30a302f8238c8cff9f8a (diff)
Youtube player support
Diffstat (limited to 'src/client/players')
-rw-r--r--src/client/players/Raw.hx17
-rw-r--r--src/client/players/Youtube.hx145
2 files changed, 161 insertions, 1 deletions
diff --git a/src/client/players/Raw.hx b/src/client/players/Raw.hx
index 41b421c..1e5d245 100644
--- a/src/client/players/Raw.hx
+++ b/src/client/players/Raw.hx
@@ -11,14 +11,29 @@ class Raw implements IPlayer {
final main:Main;
final player:Player;
- var video:VideoElement;
final playerEl:Element = ge("#ytapiplayer");
+ var video:VideoElement;
public function new(main:Main, player:Player) {
this.main = main;
this.player = player;
}
+ public function getRemoteDuration(src:String, callback:(duration:Float)->Void):Void {
+ final video = document.createVideoElement();
+ video.src = src;
+ // TODO catch errors on AddVideo and getRemoteVideoDuration
+ video.onerror = e -> {
+ if (playerEl.contains(video)) playerEl.removeChild(video);
+ callback(0);
+ }
+ video.onloadedmetadata = () -> {
+ if (playerEl.contains(video)) playerEl.removeChild(video);
+ callback(video.duration);
+ }
+ Utils.prepend(playerEl, video);
+ }
+
public function loadVideo(item:VideoItem):Void {
video = document.createVideoElement();
video.id = "videoplayer";
diff --git a/src/client/players/Youtube.hx b/src/client/players/Youtube.hx
new file mode 100644
index 0000000..cba3fc4
--- /dev/null
+++ b/src/client/players/Youtube.hx
@@ -0,0 +1,145 @@
+package client.players;
+
+import js.html.Element;
+import js.Browser.document;
+import client.Main.ge;
+import js.youtube.Youtube as YtInit;
+import js.youtube.YoutubePlayer;
+import Types.VideoItem;
+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_-]+)/;
+ final main:Main;
+ final player:Player;
+ final playerEl:Element = ge("#ytapiplayer");
+ var video:Element;
+ var youtube:YoutubePlayer;
+ var isLoaded = false;
+
+ public function new(main:Main, player:Player) {
+ this.main = main;
+ this.player = player;
+ }
+
+ public static function isYoutube(url:String):Bool {
+ if (url.contains("youtu.be/")) {
+ return matchShort.match(url);
+ }
+ if (url.contains("youtube.com/embed/")) {
+ return matchEmbed.match(url);
+ }
+ if (!url.contains("youtube.com/")) return false;
+ return matchId.match(url);
+ }
+
+ function extractVideoId(url:String):String {
+ if (url.contains("youtu.be/")) {
+ matchShort.match(url);
+ return matchShort.matched(1);
+ }
+ if (url.contains("youtube.com/embed/")) {
+ matchEmbed.match(url);
+ return matchEmbed.matched(1);
+ }
+ matchId.match(url);
+ return matchId.matched(1);
+ }
+
+ public function getRemoteDuration(url:String, callback:(duration:Float)->Void):Void {
+ if (!YtInit.isLoadedAPI) {
+ YtInit.init(() -> getRemoteDuration(url, callback));
+ return;
+ }
+ final video = document.createDivElement();
+ video.id = "temp-videoplayer";
+ Utils.prepend(playerEl, video);
+ youtube = new YoutubePlayer(video.id, {
+ videoId: extractVideoId(url),
+ playerVars: {
+ modestbranding: 1,
+ rel: 0,
+ showinfo: 0
+ },
+ events: {
+ onReady: e -> {
+ if (playerEl.contains(video)) playerEl.removeChild(video);
+ callback(youtube.getDuration());
+ },
+ onError: e -> {
+ trace('Error ${e.data}');
+ if (playerEl.contains(video)) playerEl.removeChild(video);
+ callback(0);
+ }
+ }
+ });
+ }
+
+ public function loadVideo(item:VideoItem):Void {
+ if (!YtInit.isLoadedAPI) {
+ YtInit.init(() -> loadVideo(item));
+ return;
+ }
+ video = document.createDivElement();
+ video.id = "videoplayer";
+ playerEl.appendChild(video);
+
+ youtube = new YoutubePlayer(video.id, {
+ videoId: extractVideoId(item.url),
+ playerVars: {
+ autoplay: 1,
+ modestbranding: 1,
+ rel: 0,
+ showinfo: 0,
+ },
+ events: {
+ // onReady: e -> player.onCanBePlayed(),
+ onStateChange: e -> {
+ switch (e.data) {
+ case UNSTARTED:
+ isLoaded = true;
+ player.onCanBePlayed();
+ case ENDED:
+ case PLAYING:
+ player.onPlay();
+ case PAUSED:
+ player.onPause();
+ case BUFFERING:
+ player.onSetTime();
+ case CUED:
+ }
+ }
+ }
+ });
+ }
+
+ public function removeVideo():Void {
+ if (video == null) return;
+ playerEl.removeChild(video);
+ video = null;
+ }
+
+ public function play():Void {
+ if (!isLoaded) return;
+ youtube.playVideo();
+ }
+
+ public function pause():Void {
+ if (!isLoaded) return;
+ youtube.pauseVideo();
+ }
+
+ public function getTime():Float {
+ if (!isLoaded) return 0;
+ return youtube.getCurrentTime();
+ }
+
+ public function setTime(time:Float):Void {
+ if (!isLoaded) return;
+ youtube.seekTo((time : Any), true);
+ }
+
+}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage