Last active
January 25, 2021 21:48
-
-
Save jitingcn/efd3501825dd8cb812e984212c1f9dfc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# frozen_string_literal: true | |
require 'colorize' | |
require 'open3' | |
require 'json' | |
require 'tempfile' | |
def parse_info(filename) | |
data = JSON.load File.open(filename) | |
data['formats'].map do |format| | |
first_fragment = format['fragments'][0] | |
first_fragment_id = first_fragment['path'].match(/sq\/(.*)\/lmt\//)[1].to_i | |
duration = first_fragment['duration'] | |
unless first_fragment_id.zero? | |
format['fragments'] = first_fragment_id.times.map do |i| | |
{ 'duration': duration, 'path': "sq/#{i}" } | |
end.push(*format['fragments']) | |
end | |
format | |
end | |
data | |
rescue StandardError => e | |
puts e.message | |
end | |
if ARGV.length.positive? | |
if ARGV.length == 1 # match youtube link | |
text = ARGV[0] | |
patten = %r{(?:https?:\/\/)?(?:youtu\.be\/|(?:www\.|m\.)?youtube\.com\/(?:watch|v|embed)(?:\.php)?(?:\?.*v=|\/))([a-zA-Z0-9\-_]+)} | |
if text.match?(patten) | |
puts "[download] #{text.match(patten)}".light_blue | |
begin | |
`youtube-dl -f 'bestvideo[ext=mp4],bestaudio/best' --skip-download --write-info-json -o temp '#{text.match(patten)}'` | |
info_json = Tempfile.open('ytb-', '/tmp') | |
info_json.write JSON.generate(parse_info('temp.info.json'), ascii_only: true) | |
info_json.close | |
`rm 'temp.info.json'` | |
`cp #{info_json.path} debug.json` | |
cmd = "youtube-dl --write-description -o '%(upload_date)s-%(title)s-%(id)s.%(ext)s' --buffer-size 32K --http-chunk-size 10M --external-downloader ffmpeg -f 'bestvideo[ext=mp4],bestaudio/best' --load-info-json '#{info_json.path}' 1>&2" | |
Thread.report_on_exception = false | |
_stdout, stderr, exit_status = Open3.capture3(cmd) | |
info_json.unlink | |
rescue Interrupt | |
puts 'Interrupt'.red.underline | |
info_json.unlink | |
exit | |
end | |
Thread.report_on_exception = true | |
exit unless exit_status.success? | |
puts "successful.".light_blue.blink | |
result = stderr.to_s.scan(/Destination:\ (.+)/).flatten | |
result = stderr.to_s.scan(/\[download\] (.+) has already been downloaded/).flatten if result.size.eql? 0 | |
exit unless result.size.eql? 2 | |
video = result[0] | |
audio = result[1] | |
else | |
video = Dir.glob(text + '.mp4').reject { |f| f.include? 'muxed' } [0] | |
audio = Dir.glob(text + '.*').select { |f| File.extname(f) == '.webm' or File.extname(f) == '.m4a' } [0] | |
end | |
elsif ARGV.length == 2 | |
video = ARGV[0] | |
audio = ARGV[1] | |
end | |
filelist = [audio, video] | |
else | |
filelist = (Dir.glob('*.webm') + Dir.glob('*.mp4') + Dir.glob('*.m4a')) | |
.select {|f| !f.include? 'muxed' } | |
.select {|f| File.readable? f.to_s } | |
.sort | |
.reverse | |
puts filelist.size.to_s.light_blue | |
end | |
Dir.glob("*.description") do |f| | |
puts "rename #{f} to #{f}.txt" | |
`mv '#{f}' '#{f}.txt'` | |
end | |
filelist.each_slice(2) do |a, v| | |
unless File.basename(a, ".*") == File.basename(v, ".*") # && | |
# (File.extname(audio) == ".webm" || File.extname(audio) == ".m4a") && | |
# File.extname(video) == ".mp4" | |
puts "video: #{v}\naudio: #{a}" .light_blue | |
puts "error: mismatch input" .red .blink | |
exit | |
else | |
output = "#{v[0...-4]}-muxed.mp4" | |
end | |
`ffmpeg -hide_banner -y -i '#{v}' -i '#{a}' -c:v copy -c:a libfdk_aac -vbr 5 -ar 44100 '#{output}'` | |
unless $?.success? | |
puts 'error'.red.blink | |
exit | |
end | |
if File.exist? output.to_s | |
`rm '#{v}'` | |
puts "delete file: '#{v}' success".colorize(:light_blue) | |
`rm '#{a}'` | |
puts "delete file: '#{a}' success".colorize(:light_blue) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment