Преглед изворни кода

Use youtube-dl instead of WWW::YouTube::Download

Zachary Kotlarek пре 11 година
родитељ
комит
1c549e8d55
1 измењених фајлова са 28 додато и 68 уклоњено
  1. 28 68
      yt/subscribe.pl

+ 28 - 68
yt/subscribe.pl

@@ -11,17 +11,16 @@ use LWP::Simple;
 use URI::Escape;
 use URI::Escape;
 use JSON;
 use JSON;
 use XML::LibXML;
 use XML::LibXML;
-use IPC::System::Simple qw( system );
+use IPC::System::Simple qw( system run EXIT_ANY $EXITVAL );
 use IPC::Cmd qw( can_run );
 use IPC::Cmd qw( can_run );
-use WWW::YouTube::Download;
 use PrettyPrint;
 use PrettyPrint;
 
 
 # Paramters
 # Paramters
 my %USERS           = ('profplump' => 'kj-Ob6eYHvzo-P0UWfnQzA', 'shanda' => 'hfwMHzkPXOOFDce5hyQkTA');
 my %USERS           = ('profplump' => 'kj-Ob6eYHvzo-P0UWfnQzA', 'shanda' => 'hfwMHzkPXOOFDce5hyQkTA');
 my $EXTRAS_FILE     = 'extra_videos.ini';
 my $EXTRAS_FILE     = 'extra_videos.ini';
 my $EXCLUDES_FILE   = 'exclude_videos.ini';
 my $EXCLUDES_FILE   = 'exclude_videos.ini';
-my $CURL_BIN        = 'curl';
-my @CURL_ARGS       = ('-4', '--insecure', '-H', 'Accept-Encoding: gzip', '-C', '-', '--connect-timeout', '10', '--max-time', '1800');
+my $YTDL_BIN        = $ENV{'HOME'} . '/bin/video/yt/youtube-dl';
+my @YTDL_ARGS       = ('--force-ipv4', '--no-playlist', '--max-downloads', '1', '--age-limit', '99');
 my $BATCH_SIZE      = 50;
 my $BATCH_SIZE      = 50;
 my $MAX_INDEX       = 25000;
 my $MAX_INDEX       = 25000;
 my $DRIFT_TOLERANCE = 2;
 my $DRIFT_TOLERANCE = 2;
@@ -75,7 +74,6 @@ my %API             = (
 sub findVideos($);
 sub findVideos($);
 sub findFiles();
 sub findFiles();
 sub findVideo($);
 sub findVideo($);
-sub ytURL($);
 sub buildNFO($);
 sub buildNFO($);
 sub buildSeriesNFO($);
 sub buildSeriesNFO($);
 sub getSubscriptions($$);
 sub getSubscriptions($$);
@@ -90,7 +88,8 @@ sub parseVideoData($);
 sub dropExcludes($);
 sub dropExcludes($);
 sub addExtras($);
 sub addExtras($);
 sub updateNFOData($$$);
 sub updateNFOData($$$);
-sub videoPath($$$);
+sub videoSE($$);
+sub videoPath($$$$);
 sub renameVideo($$$$$);
 sub renameVideo($$$$$);
 
 
 # Sanity check
 # Sanity check
@@ -177,7 +176,7 @@ foreach my $key (keys(%API)) {
 	}
 	}
 }
 }
 if (!$DEBUG) {
 if (!$DEBUG) {
-	push(@CURL_ARGS, '--silent');
+	push(@YTDL_ARGS, '--quiet', '--no-warnings');
 }
 }
 
 
 # Allow use as a subscription manager
 # Allow use as a subscription manager
@@ -252,8 +251,7 @@ foreach my $id (keys(%{$files})) {
 
 
 # Fill in missing videos and NFOs
 # Fill in missing videos and NFOs
 foreach my $id (keys(%{$videos})) {
 foreach my $id (keys(%{$videos})) {
-	my $basePath = videoPath($videos->{$id}->{'season'}, $videos->{$id}->{'number'}, $id);
-	my $nfo = $basePath . 'nfo';
+	my $nfo = videoPath($videos->{$id}->{'season'}, $videos->{$id}->{'number'}, $id, 'nfo');
 
 
 	# Warn (and optionally rename) if the video numbers drift
 	# Warn (and optionally rename) if the video numbers drift
 	if (
 	if (
@@ -299,19 +297,11 @@ foreach my $id (keys(%{$videos})) {
 			print STDERR 'Fetching video: ' . $id . "\n";
 			print STDERR 'Fetching video: ' . $id . "\n";
 		}
 		}
 
 
-		# Find the download URL and file suffix
-		my ($url, $suffix) = ytURL($id);
-		if (!defined($url) || length($url) < 5) {
-			warn('Could not determine URL for video: ' . $id . "\n");
-			$url = undef();
-		}
-
-		# Fetch with cURL
-		# I know LWP exists (and is even loaded) but cURL makes my life easier
-		if ($url) {
-			my @cmd = ($CURL_BIN);
-			push(@cmd, @CURL_ARGS);
-			push(@cmd, '-o', $basePath . $suffix, $url);
+		# Let youtube-dl handle the URLs and downloading
+		{
+			my @cmd = ($YTDL_BIN);
+			push(@cmd, @YTDL_ARGS);
+			push(@cmd, '--output', videoSE($videos->{$id}->{'season'}, $videos->{$id}->{'number'}) . '%(id)s.%(ext)s', $id);
 			if ($NO_FETCH) {
 			if ($NO_FETCH) {
 				print STDERR 'Not running: ' . join(' ', @cmd) . "\n";
 				print STDERR 'Not running: ' . join(' ', @cmd) . "\n";
 			} else {
 			} else {
@@ -319,7 +309,11 @@ foreach my $id (keys(%{$videos})) {
 					print STDERR join(' ', @cmd) . "\n";
 					print STDERR join(' ', @cmd) . "\n";
 				}
 				}
 				sleep($DELAY);
 				sleep($DELAY);
-				system(@cmd);
+				my $exit = run(EXIT_ANY, @cmd);
+				if ($exit != 0) {
+					warn('Error executing youtube-dl: ' . $exit . "\n");
+					next;
+				}
 			}
 			}
 		}
 		}
 
 
@@ -437,45 +431,6 @@ sub buildNFO($) {
 	return $doc->toString();
 	return $doc->toString();
 }
 }
 
 
-sub ytURL($) {
-	my ($id) = @_;
-
-	# Init the YT object
-	my $tube = WWW::YouTube::Download->new;
-
-	# Fetch metadata
-	my $meta = eval { $tube->prepare_download($id); };
-	if (!defined($meta) || ref($meta) ne 'HASH' || !exists($meta->{'video_url_map'}) || ref($meta->{'video_url_map'}) ne 'HASH') {
-		if ($@ =~ /age gate/i) {
-			print STDERR "Video not available due to age gate restrictions\n";
-		}
-		return undef();
-	}
-
-	# Find the best stream (i.e. highest resolution, prefer mp4)
-	my $bestStream     = undef();
-	my $bestResolution = 0;
-	foreach my $streamID (keys(%{ $meta->{'video_url_map'} })) {
-		my $stream = $meta->{'video_url_map'}->{$streamID};
-		my ($res) = $stream->{'resolution'} =~ /^\s*(\d+)/;
-		if ($DEBUG > 1) {
-			print STDERR $streamID . ' (' . $stream->{'suffix'} . ')' . ' => ' . $stream->{'resolution'} . ' : ' . $stream->{'url'} . "\n";
-		}
-		if (   ($res > $bestResolution)
-			|| ($res == $bestResolution && defined($bestStream) && $bestStream->{'suffix'} ne 'mp4'))
-		{
-			$bestStream     = $stream;
-			$bestResolution = $res;
-		}
-	}
-
-	if (!exists($bestStream->{'suffix'}) || length($bestStream->{'suffix'}) < 2) {
-		$bestStream->{'suffix'} = 'mp4';
-	}
-
-	return ($bestStream->{'url'}, $bestStream->{'suffix'});
-}
-
 sub findFiles() {
 sub findFiles() {
 	my %files = ();
 	my %files = ();
 
 
@@ -924,9 +879,15 @@ sub updateNFOData($$$) {
 	return $nfoData;
 	return $nfoData;
 }
 }
 
 
-sub videoPath($$$) {
-	my ($season, $episode, $id) = @_;
-	return sprintf('S%02dE%02d - %s.', $season, $episode, $id);
+sub videoSE($$) {
+	my ($season, $episode) = @_;
+	return sprintf('S%02dE%02d - ', $season, $episode);
+
+}
+
+sub videoPath($$$$) {
+	my ($season, $episode, $id, $ext) = @_;
+	return videoSE($season, $episode) . $id . '.' . $ext;
 }
 }
 
 
 sub renameVideo($$$$$) {
 sub renameVideo($$$$$) {
@@ -948,9 +909,8 @@ sub renameVideo($$$$$) {
 	$nfo =~ s/\.${suffix}$/\.nfo/;
 	$nfo =~ s/\.${suffix}$/\.nfo/;
 
 
 	# Build a new path
 	# Build a new path
-	my $base     = videoPath($season, $episode, $id);
-	my $videoNew = $base . $suffix;
-	my $nfoNew   = $base . 'nfo';
+	my $videoNew = videoPath($season, $episode, $id, $suffix);
+	my $nfoNew   = videoPath($season, $episode, $id, 'nfo');
 	print STDERR 'Renaming ' . $video . ' => ' . $videoNew . "\n";
 	print STDERR 'Renaming ' . $video . ' => ' . $videoNew . "\n";
 
 
 	# Parse old NFO data
 	# Parse old NFO data