yt-track-split 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use Time::Piece;
  5. if ( ! defined $ARGV[0] || ! defined $ARGV[1] ) {
  6. print "Need to pass args\n";
  7. exit 1;
  8. }
  9. my $ffmpegBin = `which ffmpeg`;
  10. chomp $ffmpegBin;
  11. if ( ! -e $ffmpegBin ) {
  12. print "You need ffmpeg installed to use this\n";
  13. exit 1;
  14. }
  15. my $track_list_path = shift(@ARGV);
  16. my $full_file_path = shift(@ARGV);
  17. my $track_list_file = `cat $track_list_path`;
  18. chomp $track_list_file;
  19. # Key is track name - val is array ref containing start time and end time
  20. my %track_times;
  21. my %track_names;
  22. sub prepend_zeros($) {
  23. my $time = shift;
  24. if ( $time =~ m/^[0-9]{1,2}\:[0-9]{2}$/ ) {
  25. if ( length $time == 4 ) {
  26. $time = "00:0" . $time;
  27. } elsif ( length $time == 5 ) {
  28. $time = "00:" . $time;
  29. } elsif ( length $time == 7 ) {
  30. $time = "0" . $time;
  31. } elsif ( length $time == 8 ) {
  32. # Don't need to do anything
  33. } else {
  34. print "Couldn't prepend zero's for $time\n";
  35. my $len = length $time;
  36. print "length of $time is $len\n";
  37. exit 1;
  38. }
  39. }
  40. return $time;
  41. }
  42. sub remove_spaces($) {
  43. my $track_name = shift;
  44. if ( $track_name =~ m/\s/ ) {
  45. $track_name =~ s/\s/_/g;
  46. return $track_name;
  47. }
  48. return $track_name;
  49. }
  50. sub get_end_time($$) {
  51. my $start_time = shift;
  52. my $next_start_time = shift;
  53. my $end_time;
  54. if ( $next_start_time =~ m/^(.*)\:([0-9]{2})$/ ) {
  55. my $end_time_val = $2 - 1;
  56. $end_time = $1 . ":" . $end_time_val;
  57. $end_time = prepend_zeros($end_time);
  58. return $end_time;
  59. } else {
  60. print "get_end_time couldn't match regex on $next_start_time - exiting\n";
  61. exit 1;
  62. }
  63. }
  64. sub get_track_length() {
  65. my $ffmpegCmd = "$ffmpegBin -i '$full_file_path' 2>&1";
  66. my $ffmpegOutput = `$ffmpegCmd`;
  67. chomp $ffmpegOutput;
  68. if ( ! defined $ffmpegOutput || $ffmpegOutput eq "" ) {
  69. print "Something went wrong with calling $ffmpegCmd\n";
  70. exit 1;
  71. }
  72. my $duration;
  73. foreach my $line ( split("\n", $ffmpegOutput) ) {
  74. if ( $line =~ m/Duration:\ (.*)\.[0-9]{2},/ ) {
  75. $duration = $1;
  76. return $duration;
  77. }
  78. }
  79. print "Couldnt get duration of $full_file_path from $ffmpegCmd\n";
  80. exit 1;
  81. }
  82. sub run_split($$$$) {
  83. # ffmpeg -i Ryo\ Fukui\ -\ Scenery\ 1976\ \(FULL\ ALBUM\)-Hrr3dp7zRQY.mp4 -acodec copy -ss 00:00:00 -to 00:04:15 shibz.mp4
  84. my $track_number = shift;
  85. my $track_name = shift;
  86. my $start_time = shift;
  87. my $end_time = shift;
  88. # Optionally covert to different codec?
  89. my $filename = "$track_number" . "-" . "$track_name" . ".mp4";
  90. my $ffmpegCmd = "$ffmpegBin -i '$full_file_path' -acodec copy -ss $start_time -to $end_time $filename 2>&1 > /dev/null";
  91. system("$ffmpegCmd") == 0 or die "Failed to run $ffmpegCmd\n";
  92. }
  93. foreach my $line ( split("\n",$track_list_file) ) {
  94. #if ( $line =~ m/^([0-9]{1,2})\.\ (.*)\ ([0-9]{1,2}:[0-9]{2})$/ ) {
  95. if ( $line =~ m/^([0-9]{1,2})\.\ (.*)\ (.*)$/ ) {
  96. my @times;
  97. # Start time
  98. my $start_time = prepend_zeros($3);
  99. push(@times, $start_time);
  100. $track_times{$1} = \@times;
  101. my $track_name = remove_spaces($2);
  102. $track_names{$1} = $track_name;
  103. } else {
  104. print "$line doesn't match regex, exiting\n";
  105. exit 1;
  106. }
  107. }
  108. foreach my $track_number ( sort keys %track_times ) {
  109. my $next_track_val = $track_number + 1;
  110. my $next_start_time;
  111. my $end_time;
  112. if ( defined $track_times{$next_track_val} ) {
  113. $next_start_time = $track_times{$next_track_val}[0];
  114. $end_time = get_end_time($track_times{$track_number}[0],$next_start_time);
  115. } else {
  116. $end_time = get_track_length;
  117. }
  118. push(@{$track_times{$track_number}}, $end_time);
  119. }
  120. foreach my $track_number ( sort keys %track_times ) {
  121. print "Splitting $track_number - $track_names{$track_number} - $track_times{$track_number}[0] - $track_times{$track_number}[1]\n";
  122. run_split($track_number,$track_names{$track_number},$track_times{$track_number}[0],$track_times{$track_number}[1]);
  123. }