any2mp3.sf 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 17 June 2014
  4. # Edit: 21 March 2020
  5. # Website: https://github.com/trizen
  6. # Convert any media file to MP3, using `n` parallel processes of ffmpeg.
  7. func usage(code=0) {
  8. var name = File(__FILE__).basename
  9. print <<"USAGE"
  10. usage:
  11. #{name} [options] [input files]
  12. options:
  13. -b --bitrate=i : MP3 bitrate (default: 192K)
  14. -t --threads=i : use this many threads (default: 2)
  15. -o --outdir=s : output directory (default: .)
  16. example:
  17. #{name} -t 4 *.mp4 # convert MP4 to MP3
  18. USAGE
  19. Sys.exit(code)
  20. }
  21. func executeCmd(cmd, arg) {
  22. Sys.run(cmd, arg...)
  23. }
  24. func wait_th(forks) {
  25. say ":: Running threads: #{forks.len}"
  26. say ":: FFmpeg exit-code: #{forks.pop_rand.wait}"
  27. }
  28. func main() {
  29. const extensionRe = %r/\.\w{1,5}\z/
  30. const outputFormat = "mp3"
  31. const ffmpegCmd = "ffmpeg"
  32. var bitrate = 192
  33. var maxThreads = 2
  34. var outputDir = Dir.cwd
  35. ARGV.getopt!(
  36. 'b|bitrate=i' => \bitrate,
  37. 'o|outdir=s' => \outputDir,
  38. 't|threads=i' => \maxThreads,
  39. 'h|help' => usage,
  40. )
  41. var ffmpegArg = ["-loglevel", "fatal", "-y", "-vn", "-ac", "2", "-ab", "#{bitrate}K", "-ar", "48000", "-f", outputFormat]
  42. if (ARGV.len == 0) {
  43. Sys.warn("\n[!] No input file has been provided!\n")
  44. usage(2)
  45. }
  46. if (!outputDir.exists) {
  47. outputDir.create || die "Can't create dir `#{outputDir}': #{$!}"
  48. }
  49. var forks = []
  50. var counter = 0
  51. ARGV.each { |entry|
  52. var file = File(entry)
  53. if (!file.exists) {
  54. Sys.warn("File `#{file}' does not exists! Skipping file...\n")
  55. next
  56. }
  57. if (!file.is_file) {
  58. Sys.warn("File `#{file}' is not a plain file! Skipping it...\n")
  59. next
  60. }
  61. var outputFile = file.basename.sub(extensionRe)
  62. outputFile = File(outputDir, outputFile + '.' + outputFormat)
  63. printf("[%2d] %s -> %s\n", counter++, file, outputFile)
  64. var args = ['-i', file.to_s, ffmpegArg..., outputFile]
  65. forks.append(executeCmd.ffork(ffmpegCmd, args))
  66. if (forks.len >= maxThreads) {
  67. wait_th(forks)
  68. }
  69. }
  70. while (forks.len > 0) {
  71. wait_th(forks)
  72. }
  73. if (counter > 0) {
  74. say ":: All done!"
  75. }
  76. }
  77. main()