aboutsummaryrefslogtreecommitdiffstats
path: root/src/client/players
diff options
context:
space:
mode:
authorRblSb <msrblsb@gmail.com>2020-03-08 03:20:52 +0300
committerRblSb <msrblsb@gmail.com>2020-03-08 03:20:52 +0300
commit4df4f2d023d7c2413fb5d6bf9597ce409c3354be (patch)
tree9385e57e234e3c27ba1ce3433c63df38a92c3702 /src/client/players
parentc6709732e858d111a75d14f8b9a132c58487f8d8 (diff)
Youtube playlists and api key in config
Diffstat (limited to 'src/client/players')
-rw-r--r--src/client/players/Youtube.hx83
1 files changed, 68 insertions, 15 deletions
diff --git a/src/client/players/Youtube.hx b/src/client/players/Youtube.hx
index 15eb014..f582ba7 100644
--- a/src/client/players/Youtube.hx
+++ b/src/client/players/Youtube.hx
@@ -16,9 +16,12 @@ 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 apiUrl = "https://www.googleapis.com/youtube/v3/videos";
+ 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 apiKey = "AIzaSyDTk1OPRI9cDkAK_BKsBcv10DQCHse-QaA";
+ static final urlVideoId = "?part=snippet&fields=items(snippet/resourceId/videoId)";
+ static var apiKey:String;
final main:Main;
final player:Player;
final playerEl:Element = ge("#ytapiplayer");
@@ -29,10 +32,11 @@ class Youtube implements IPlayer {
public function new(main:Main, player:Player) {
this.main = main;
this.player = player;
+ apiKey = main.getYoutubeApiKey();
}
public static function isYoutube(url:String):Bool {
- return extractVideoId(url) != "";
+ return extractVideoId(url) != "" || extractPlaylistId(url) != "";
}
static function extractVideoId(url:String):String {
@@ -48,6 +52,11 @@ class Youtube implements IPlayer {
return matchId.matched(1);
}
+ static function extractPlaylistId(url:String):String {
+ if (!matchPlaylist.match(url)) return "";
+ return matchPlaylist.matched(1);
+ }
+
final matchHours = ~/([0-9]+)H/;
final matchMinutes = ~/([0-9]+)M/;
final matchSeconds = ~/([0-9]+)S/;
@@ -64,32 +73,76 @@ class Youtube implements IPlayer {
}
public function getVideoData(url:String, callback:(data:VideoData)->Void):Void {
- final id = extractVideoId(url);
- final url = '$apiUrl$urlTitleDuration&id=$id&key=$apiKey';
- final http = new Http(url);
+ var id = extractVideoId(url);
+ if (id == "") {
+ getPlaylistVideoData(url, callback);
+ return;
+ }
+ final dataUrl = '$videosUrl$urlTitleDuration&id=$id&key=$apiKey';
+ final http = new Http(dataUrl);
http.onData = data -> {
final json = Json.parse(data);
if (json.error != null) {
+ youtubeApiError(json.error);
getRemoteDataFallback(url, callback);
return;
}
- final item = json.items[0];
- if (item == null) {
+ final items:Array<Dynamic> = json.items;
+ if (items == null || items.length == 0) {
callback({duration: 0});
return;
}
- final title:String = item.snippet.title;
- final duration:String = item.contentDetails.duration;
- // TODO duration is PT0S for streams
- callback({
- duration: convertTime(duration),
- title: title
- });
+ for (item in items) {
+ final title:String = item.snippet.title;
+ final duration:String = item.contentDetails.duration;
+ // TODO duration is PT0S for streams
+ callback({
+ duration: convertTime(duration),
+ title: title,
+ url: url
+ });
+ }
}
http.onError = msg -> getRemoteDataFallback(url, callback);
http.request();
}
+ function getPlaylistVideoData(url:String, callback:(data:VideoData)->Void):Void {
+ final id = extractPlaylistId(url);
+ final dataUrl = '$playlistUrl$urlVideoId&maxResults=50&playlistId=$id&key=$apiKey';
+ final http = new Http(dataUrl);
+ http.onData = data -> {
+ final json = Json.parse(data);
+ if (json.error != null) {
+ youtubeApiError(json.error);
+ callback({duration: 0});
+ return;
+ }
+ final items:Array<Dynamic> = json.items;
+ if (items == null || items.length == 0) {
+ callback({duration: 0});
+ return;
+ }
+ function loadNextItem():Void {
+ final item = items.shift();
+ final id:String = item.snippet.resourceId.videoId;
+ getVideoData('youtu.be/$id', data -> {
+ callback(data);
+ if (items.length > 0) loadNextItem();
+ });
+ }
+ loadNextItem();
+ }
+ http.onError = msg -> callback({duration: 0});
+ http.request();
+ }
+
+ function youtubeApiError(error:Dynamic):Void {
+ final code:Int = error.code;
+ final msg:String = error.message;
+ main.serverMessage(4, 'Error $code: $msg', false);
+ }
+
function getRemoteDataFallback(url:String, callback:(data:VideoData)->Void):Void {
if (!YtInit.isLoadedAPI) {
YtInit.init(() -> getRemoteDataFallback(url, callback));
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage