fetch.pl 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use FindBin;
  5. use lib "$FindBin::Bin/";
  6. use File::Touch;
  7. use File::Basename;
  8. use IPC::System::Simple qw( system run capture EXIT_ANY $EXITVAL );
  9. use IPC::Cmd qw( can_run );
  10. use Cwd qw( abs_path );
  11. # Paramters
  12. my $YTDL_BIN = $ENV{'HOME'} . '/bin/video/yt/youtube-dl';
  13. my @YTDL_ARGS = ('--force-ipv4', '--socket-timeout', '10', '--retries', '1',
  14. '--no-playlist', '--max-downloads', '1', '--age-limit', '99');
  15. my @YTDL_QUIET = ('--quiet', '--no-warnings');
  16. my @YTDL_DEBUG = ('--verbose');
  17. # Debug
  18. my $DEBUG = 0;
  19. if ($ENV{'DEBUG'}) {
  20. if ($ENV{'DEBUG'} =~ /(\d+)/) {
  21. $DEBUG = $1;
  22. } else {
  23. $DEBUG = 1;
  24. }
  25. }
  26. # Sanity check
  27. if (scalar(@ARGV) < 1) {
  28. die('Usage: ' . basename($0) . " output_directory\n");
  29. }
  30. if ($DEBUG) {
  31. print STDERR 'Fetching video: ' . $id . "\n";
  32. }
  33. my $reviewed = videoSE($videos->{$id}->{'season'}, $videos->{$id}->{'number'}) . $id . '.reviewed';
  34. touch($reviewed);
  35. my @args = ('--output', videoSE($videos->{$id}->{'season'}, $videos->{$id}->{'number'}) . '%(id)s.%(ext)s', '--', $id);
  36. my @name = ($YTDL_BIN);
  37. push(@name, @YTDL_ARGS);
  38. my @fetch = @name;
  39. push(@name, '--get-filename');
  40. push(@fetch, @args);
  41. push(@name, @args);
  42. # Count fetch attempts (even if they fail later)
  43. $fetched++;
  44. if ($FETCH_LIMIT && $fetched > $FETCH_LIMIT) {
  45. print STDERR 'Reached fetch limit (' . $FETCH_LIMIT . ') for: ' . $NAME . "\n";
  46. if ($DEBUG) {
  47. print STDERR "\tLocal/Remote videos at start:" . scalar(keys(%{$files})) . '/' . scalar(keys(%{$videos})) . "\n";
  48. }
  49. exit 1;
  50. }
  51. # Find the output file name
  52. if ($DEBUG > 1) {
  53. print STDERR join(' ', @name) . "\n";
  54. }
  55. delay();
  56. my $file = capture(EXIT_ANY, @name);
  57. if ($EXITVAL != 0) {
  58. warn('Error executing youtube-dl for name: ' . $NAME . '/' . $id . ' (' . $EXITVAL . ")\n");
  59. next FETCH_LOOP;
  60. }
  61. if ($file =~ /\n\S/) {
  62. $file =~ s/^.*\n//;
  63. }
  64. $file =~ s/^\s+//;
  65. $file =~ s/\s+$//;
  66. # Sanity check
  67. if (!$file) {
  68. warn('No file name available for video: ' . $NAME . '/' . $id . "\n");
  69. next FETCH_LOOP;
  70. } elsif ($DEBUG > 0) {
  71. print STDERR 'Output video file: ' . $file . "\n";
  72. }
  73. # Download
  74. if ($DEBUG > 1) {
  75. print STDERR join(' ', @fetch) . "\n";
  76. }
  77. delay();
  78. my $exit = run(EXIT_ANY, @fetch);
  79. if ($exit != 0) {
  80. if ($DEBUG) {
  81. warn('Error executing youtube-dl for video: ' . $NAME . '/' . $id . "\n");
  82. }
  83. next FETCH_LOOP;
  84. }
  85. # Ensure we found something useful
  86. if (-e $file . '.part') {
  87. warn('Partial download detected: ' . $NAME . '/' . $file . "\n");
  88. next FETCH_LOOP;
  89. }
  90. # Sometimes the downloader lies about file extensions
  91. if (!-s $file) {
  92. $file =~ s/\.webm$/.mp4/;
  93. }
  94. if (!-s $file) {
  95. $file =~ s/\.mp4$/.webm/;
  96. }
  97. # But we still need *a* file
  98. if (!-s $file) {
  99. warn('No output video file: ' . $NAME . '/' . $file . "\n");
  100. next FETCH_LOOP;
  101. }
  102. # Touch the file to reflect the download time rather than the upload time
  103. touch($file);