aboutsummaryrefslogtreecommitdiffstats
path: root/src/client/players
diff options
context:
space:
mode:
authorRblSb <msrblsb@gmail.com>2025-01-16 03:07:31 +0300
committerRblSb <msrblsb@gmail.com>2025-01-17 01:00:09 +0300
commitd9ca7beaa9494cf34590853901cf8be44e243775 (patch)
treef09ce979460bdf28363a922298283dfee0c506fb /src/client/players
parentf84fdc40ba817b6a2d907484b1e1500197ceeafe (diff)
Cache on server feature
Server will download video from supported players and add as raw video to playlist (only youtube is supported for now). Cache for YT player is available after installing optional dependencies, see readme. For cache size see `cacheStorageLimitGiB ` in config. There is also minor ux improvement, latest checkbox states will be keeped in local storage now.
Diffstat (limited to 'src/client/players')
-rw-r--r--src/client/players/Iframe.hx7
-rw-r--r--src/client/players/Raw.hx5
-rw-r--r--src/client/players/Youtube.hx55
3 files changed, 26 insertions, 41 deletions
diff --git a/src/client/players/Iframe.hx b/src/client/players/Iframe.hx
index 56cf319..8a2e06e 100644
--- a/src/client/players/Iframe.hx
+++ b/src/client/players/Iframe.hx
@@ -1,5 +1,6 @@
package client.players;
+import Types.PlayerType;
import Types.VideoData;
import Types.VideoDataRequest;
import Types.VideoItem;
@@ -18,13 +19,17 @@ class Iframe implements IPlayer {
this.player = player;
}
+ public function getPlayerType():PlayerType {
+ return IframeType;
+ }
+
public function isSupportedLink(url:String):Bool {
return true;
}
public function getVideoData(data:VideoDataRequest, callback:(data:VideoData) -> Void):Void {
final iframe = document.createDivElement();
- iframe.innerHTML = data.url;
+ iframe.innerHTML = data.url.trim();
if (isValidIframe(iframe)) {
callback({duration: 99 * 60 * 60});
} else {
diff --git a/src/client/players/Raw.hx b/src/client/players/Raw.hx
index 5c5b7a4..7e5e50c 100644
--- a/src/client/players/Raw.hx
+++ b/src/client/players/Raw.hx
@@ -1,5 +1,6 @@
package client.players;
+import Types.PlayerType;
import Types.VideoData;
import Types.VideoDataRequest;
import Types.VideoItem;
@@ -30,6 +31,10 @@ class Raw implements IPlayer {
this.player = player;
}
+ public function getPlayerType():PlayerType {
+ return RawType;
+ }
+
public function isSupportedLink(url:String):Bool {
return true;
}
diff --git a/src/client/players/Youtube.hx b/src/client/players/Youtube.hx
index 3ad9030..5a8921a 100644
--- a/src/client/players/Youtube.hx
+++ b/src/client/players/Youtube.hx
@@ -1,5 +1,6 @@
package client.players;
+import Types.PlayerType;
import Types.VideoData;
import Types.VideoDataRequest;
import Types.VideoItem;
@@ -23,7 +24,6 @@ class Youtube implements IPlayer {
var apiKey:String;
var video:Element;
var youtube:YoutubePlayer;
- var tempYoutube:YoutubePlayer;
var isLoaded = false;
public function new(main:Main, player:Player) {
@@ -31,6 +31,10 @@ class Youtube implements IPlayer {
this.player = player;
}
+ public function getPlayerType():PlayerType {
+ return YoutubeType;
+ }
+
public function isSupportedLink(url:String):Bool {
return extractVideoId(url) != "" || extractPlaylistId(url) != "";
}
@@ -43,6 +47,10 @@ class Youtube implements IPlayer {
return YoutubeUtils.extractPlaylistId(url);
}
+ public function isPlaylistUrl(url:String):Bool {
+ return extractVideoId(url) == "" && extractPlaylistId(url) != "";
+ }
+
final matchHours = ~/([0-9]+)H/;
final matchMinutes = ~/([0-9]+)M/;
final matchSeconds = ~/([0-9]+)S/;
@@ -93,7 +101,7 @@ class Youtube implements IPlayer {
url: '<iframe src="https://www.youtube.com/embed/$id?autoplay=1$mute" frameborder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>',
- isIframe: true
+ playerType: IframeType
});
continue;
}
@@ -168,6 +176,7 @@ class Youtube implements IPlayer {
final video = document.createDivElement();
video.id = "temp-videoplayer";
Utils.prepend(playerEl, video);
+ var tempYoutube:YoutubePlayer = null;
tempYoutube = new YoutubePlayer(video.id, {
videoId: extractVideoId(url),
playerVars: {
@@ -181,12 +190,14 @@ class Youtube implements IPlayer {
callback({
duration: tempYoutube.getDuration()
});
+ tempYoutube.destroy();
},
onError: e -> {
// TODO message error codes
trace('Error ${e.data}');
if (playerEl.contains(video)) playerEl.removeChild(video);
callback({duration: 0});
+ tempYoutube.destroy();
}
}
});
@@ -243,49 +254,13 @@ class Youtube implements IPlayer {
onError: e -> {
// TODO message error codes
trace('Error ${e.data}');
- final item = player.getCurrentItem() ?? return;
- rawSourceFallback(item.url);
+ // final item = player.getCurrentItem() ?? return;
+ // rawSourceFallback(item.url);
}
}
});
}
- function rawSourceFallback(url:String):Void {
- JsApi.once(GetYoutubeVideoInfo, event -> {
- final data = event.getYoutubeVideoInfo;
- final info = data.response;
- final format = getBestStreamFormat(info) ?? {
- trace("format not found in response info:");
- trace(info);
- return;
- };
- player.changeVideoSrc(format.url);
- });
- main.send({
- type: GetYoutubeVideoInfo,
- getYoutubeVideoInfo: {
- url: url
- }
- });
- }
-
- function getBestStreamFormat(info:YouTubeVideoInfo):Null<YoutubeVideoFormat> {
- info.formats ??= [];
- info.adaptiveFormats ??= [];
- final formats = info.adaptiveFormats.concat(info.formats);
- trace(formats);
- final qPriority = [1080, 720, 480, 360, 240];
- for (q in qPriority) {
- final quality = '${q}p';
- for (format in formats) {
- if (format.audioQuality == null) continue; // no sound
- if (format.width == null) continue; // no video
- if (format.qualityLabel == quality) return format;
- }
- }
- return null;
- }
-
public function removeVideo():Void {
if (video == null) return;
isLoaded = false;
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage