Als aktueller Trend bei Musik-Playern gibt es einen Trend, bei dem sich Menschen nicht an einem Ort versammeln und zusammen spielen können. Daher nehmen sie jeweils ein Video und bearbeiten es später, um ein Video zu erstellen und es zu veröffentlichen. Ich habe nicht viel Musikwissen und spiele es im Grunde nicht selbst. Es gibt jedoch Leute in meiner Umgebung, die mit Musik zu tun haben, und ich werde oft gebeten, Videos zu bearbeiten. Um dies zu unterstützen, habe ich mit Ruby ffmpeg ausgeführt und eine Umgebung erstellt, in der die Videobearbeitung halbautomatisch durchgeführt werden kann.
Jetzt können auch Personen ohne Wissen problemlos Performance-Videos mit Smartphones aufnehmen. … Das bedeutet aber auch, dass jeder Videos in verschiedenen Formaten, Videogrößen und Bildraten sendet. Ich denke, es gibt einen besseren Weg, um die Verschlechterung des Videos zu verhindern, aber es wird wie folgt schrittweise verarbeitet.
Da davon ausgegangen wird, dass es in einer Windows-Umgebung ausgeführt wird, sollten diejenigen, die darauf verweisen, vorsichtig sein, wie das Zeichen \ verwendet wird.
movie_on_playing.rb
control_file = ARGV[0]
cfile = File.open(control_file, "r")
def system_log( exe, workd )
fho = File.open("#{workd}\\log.txt", "a")
fho.write("#{exe}\n")
fho.close
res = system( exe )
unless(res)
puts "# Error! ffmpeg failed. See #{workd}\\log.txt to confirm command."
exit
end
end
out_width = 0
out_height = 0
movie = []
resize = []
volume = []
fadein = []
delay = []
delay_f = []
to_time = []
blackf = []
crop_xy = []
crop_size = []
skip = []
row_div = []
row_flag = true
ri = 0
for s1 in cfile
next if s1 =~ /^#/
a1 = s1.chomp.split(" ")
if(a1[0] == "ffmpeg")
ffmpeg = a1[1]
next
end
if(a1[0] == "work")
workd = a1[1]
next
end
if(a1[0] == "out")
out_file_name = a1[1]
system("title #{out_file_name}")
next
end
if(a1[0] == "movie")
movie << a1[1]
next
end
if(a1[0] == "resize")
resize << a1[1]
next
end
if(a1[0] == "volume")
volume << a1[1]
next
end
if(a1[0] == "fadein")
fadein << a1[1]
next
end
if(a1[0] == "delay")
delay << a1[1]
delay_f << a1[2] if(a1[1].to_f > 0)
next
end
if(a1[0] == "time")
to_time << a1[1]
next
end
if(a1[0] == "crop")
crop_xy << a1[1]
crop_size << a1[2]
if(row_div.size == 0)
out_width = out_width + a1[2].split("x")[0].to_i
end
if row_flag
out_height = out_height + a1[2].split("x")[1].to_i
row_flag = false
end
next
end
if(a1[0] == "skip")
skip << a1[1]
next
end
if(a1[0] == "row_div")
row_div << movie.size
row_flag = true
next
end
end
cfile.close
Dir.mkdir(workd) unless File.exist?(workd)
efile_mp4 = []
efile_mp3 = []
ovl_vx = 0
ovl_vy = 0
ovl_a = []
fho = File.open("#{workd}\\log.txt", "a")
fho.write("\n#{Time.now}\n")
fho.close
out_width_e = out_width
out_height_e = out_height
fi = 0
w_reset = false
row_div << 9999
for i in 0...movie.size
filen = movie[i].split("\\")[-1].split(".")[0]
filee = movie[i].split("\\")[-1].split(".")[1]
file_rsz = "#{filen}_#{resize[i]}"
rx = resize[i].split("x")[0]
ry = resize[i].split("x")[1]
####################
#### resize part ###
####################
if(delay[i].to_f > 0.0)
fade_time = 0
else
fade_time = -1 * delay[i].to_f
end
if(delay[i].to_f > 0)
if(fadein[i].to_i > 0)
fade_in = "fade=in:0:#{fadein[i]},"
else
fade_in = ""
end
system_log( "#{ffmpeg} -y -i \"#{movie[i]}\" -vf \"#{fade_in}scale=#{rx}:#{ry}\" \"#{workd}\\#{file_rsz}.#{filee}\"", workd ) if(skip[i] == "off")
else
system_log( "#{ffmpeg} -y -i \"#{movie[i]}\" -vf \"scale=#{rx}:#{ry}\" \"#{workd}\\#{file_rsz}.#{filee}\"", workd ) if(skip[i] == "off")
end
######################
### black mov part ###
######################
if(delay[i].to_f > 0.0)
dname = delay[i].gsub(".","p")
bfile = "black_#{resize[i]}_#{dname}.#{filee}"
if(delay_f[fi] == nil)
frate = "30000/1001"
else
frate = delay_f[fi]
end
system_log( "#{ffmpeg} -y -f lavfi -i \"color=c=black:s=#{resize[i]}:r=#{frate}:d=#{delay[i]}\" -f lavfi -i \"aevalsrc=0|0:c=stereo:s=44100:d=#{delay[i]}\" \"#{workd}\\#{bfile}\"", workd ) if(skip[i] == "off")
blackf << bfile
fi = fi + 1
else
blackf << "black_0"
end
#######################
### concat/cut part ###
#######################
if(blackf[i] != "black_0")
# add plus delay
con_filen = "#{workd}\\concat_#{i}.txt"
con_file = File.open(con_filen, "w")
con_file.write("file #{workd}/#{blackf[i]}\n")
con_file.write("file #{workd}/#{file_rsz}.#{filee}\n")
con_file.close
file_cn = "#{file_rsz}_con"
system_log( "#{ffmpeg} -y -safe 0 -f concat -i \"#{con_filen}\" -c:v copy -c:a copy -map 0:v -map 0:a \"#{workd}\\#{file_cn}.#{filee}\"", workd ) if(skip[i] == "off")
elsif(delay[i].to_f < 0)
# add minus delay
cut_time = -1 * delay[i].to_f
file_ct = "#{filen}_cut"
system_log( "#{ffmpeg} -y -i \"#{workd}\\#{file_rsz}.#{filee}\" -ss #{cut_time} \"#{workd}\\#{file_ct}.#{filee}\"", workd ) if(skip[i] == "off")
file_cn = file_ct
else
# not add delay
file_cn = file_rsz
end
###########################
### fade, crop, to part ###
###########################
crop_x = crop_xy[i].split("x")[0]
crop_y = crop_xy[i].split("x")[1]
crop_w = crop_size[i].split("x")[0]
crop_h = crop_size[i].split("x")[1]
cropt = "crop=#{crop_w}:#{crop_h}:#{crop_x}:#{crop_y}"
if(w_reset)
out_width_e = out_width
out_height_e = out_height_e - crop_h.to_i
w_reset = false
end
if( out_width_e - crop_w.to_i > 0 || out_height_e - crop_h.to_i > 0)
padt = ",pad=#{out_width_e}:#{out_height_e}:0:0"
else
padt = ""
end
if(to_time[i].to_f > 0)
tot = "-to #{to_time[i].to_f + delay[i].to_f}"
else
tot = ""
end
file_crp = "#{file_rsz}_cropped"
if(delay[i].to_f > 0)
system_log( "#{ffmpeg} -y -i \"#{workd}\\#{file_cn}.#{filee}\" -vf \"#{cropt}#{padt}\" #{tot} \"#{workd}\\#{file_crp}.#{filee}\"", workd ) if(skip[i] == "off")
else
if(fadein[i].to_i > 0)
fade_in = "fade=in:0:#{fadein[i]},"
else
fade_in = ""
end
system_log( "#{ffmpeg} -y -i \"#{workd}\\#{file_cn}.#{filee}\" -vf \"#{fade_in}#{cropt}#{padt}\" #{tot} \"#{workd}\\#{file_crp}.#{filee}\"", workd ) if(skip[i] == "off")
end
out_width_e = out_width_e - crop_w.to_i
if(row_div.size > 0)
if(i == row_div[ri] - 1)
ovl_vx = 0
ovl_vy = ovl_vy + crop_h.to_i
ri = ri + 1
w_reset = true
else
ovl_vx = ovl_vx + crop_w.to_i
end
else
ovl_vx = ovl_vx + crop_w.to_i
end
ovl_a << [ovl_vx, ovl_vy]
############################
### mp3 out, volume part ###
############################
vol_e = volume[i].to_f / 100
system_log( "#{ffmpeg} -y -i \"#{workd}\\#{file_crp}.#{filee}\" -vn -acodec libmp3lame -ar 44100 -ab 256k -af \"volume=#{vol_e}\" \"#{workd}\\#{filen}.mp3\"", workd ) if(skip[i] == "off")
efile_mp3 << "#{workd}\\#{filen}.mp3"
efile_mp4 << "#{workd}\\#{file_crp}.#{filee}"
end
####################
### overlay part ###
####################
in_file = ""
for efile in efile_mp4
in_file = "#{in_file} -i \"#{efile}\""
end
ovlt = ""
for i in 0...ovl_a.size - 1
if(ovlt == "")
ovlt = "overlay=x=#{ovl_a[i][0]}:y=#{ovl_a[i][1]}"
else
ovlt = "#{ovlt},overlay=x=#{ovl_a[i][0]}:y=#{ovl_a[i][1]}"
end
end
system_log( "#{ffmpeg} -y#{in_file} -filter_complex \"#{ovlt}\" -an \"#{workd}\\out_movie.#{filee}\"", workd )
######################
### add audio part ###
######################
in_file = ""
for efile in efile_mp3
in_file = "#{in_file} -i \"#{efile}\""
end
system_log( "#{ffmpeg} -y -i \"#{workd}\\out_movie.#{filee}\" #{in_file} -filter_complex \"amix=inputs=#{efile_mp3.size}:duration=longest:dropout_transition=2\" \"#{out_file_name}\"", workd )
3.1 Control file Eine Steuerdatei wurde erstellt und gelesen, um den Speicherort der Videodatei und die Bearbeitungsmethode anzugeben. Das Folgende ist ein Beispiel. Außerdem wird das Video nach Eingabe des Schlüsselworts "row_div" vertikal statt horizontal verbunden.
control.txt
ffmpeg C:\ffmpeg\bin\ffmpeg.exe
work work
out out.mp4
movie org_data\a-san.mp4
resize 1280x720
volume 100
fadein 60
delay 1.5
time 208.5
crop 0x0 640x720
skip off
movie org_data\b-san.mp4
resize 1280x720
volume 120
fadein 60
delay -2.5
time 212.5
crop 320x0 640x720
skip off
ruby movie_on_playing.rb control.txt
Mit Befehlen wie werden ffmpeg-Befehle nacheinander generiert und basierend auf den Steuerinformationen ausgeführt.
Die Verarbeitung jedes Teils wird gemäß dem Abschnitt ○○ des Kommentarbereichs erläutert.
4.1. Resize part Ändern Sie die Größe des Videos gemäß der Einstellung "Größe ändern" in der Steuerdatei. Setzen Sie den Größenänderungswert nach "scale =" und generieren Sie den folgenden Befehl.
ffmpeg.exe -y -i "org_data\a-san.mp4" -vf "scale=1280:720" "work\a-san_1280x720.mp4"
Wenn der Wert für "Verzögerung" + ist, wird das Video, das zuvor nichts gezeigt hat, verlinkt, sodass auch hier das Einblenden eingestellt wird.
ffmpeg.exe -y -i "org_data\a-san.mp4" -vf "fade=in:0:30,scale=1280:720" "work\a-san_1280x720.mp4"
4.2. Black movie part Wenn der Wert für "Verzögerung" + ist (um den Start des Videos zu verzögern), wird ein Video ohne Video erstellt, wenn für die angegebene Anzahl von Sekunden kein Ton zu hören ist (Hinweis: nicht ohne Ton). Setzen Sie den Wert nach "d =" und generieren Sie den folgenden Befehl.
ffmpeg.exe -y -f lavfi -i "color=c=black:s=1280x720:r=30000/1001:d=1.5" -f lavfi -i "aevalsrc=0|0:c=stereo:s=44100:d=1.5" "work\black_1280x720_1p5.mp4"
Da dieser Vorgang nach der Verkettung zu Problemen im Video führt, kann der Frame in der 3. Spalte mit "Verzögerung [Sekunden] [Framerate]" geändert werden. Diese Methode funktioniert jedoch möglicherweise nicht gut. Wenn Sie ein Video mit ffmpeg bearbeiten, ist es einfacher, mit einem ausreichenden Rand des Originalvideos aufzunehmen und es dann auszuschneiden. Wenn Sie von nun an ein Video aufnehmen möchten, teilen Sie dem Darsteller mit: "Drücken Sie die Aufnahmetaste, warten Sie etwa 5 Sekunden und spielen Sie dann ab."
4.3. Concat/cut part Wenn der Wert von "delay "- ist (um das Video vorzeitig zu starten), setzen Sie ihn in den Wert von" -ss "und generieren Sie den folgenden Befehl.
ffmpeg.exe -y -i "work\a-san_1280x720.mp4" -ss 2.5 "work\a-san_1280x720_cut.mp4"
Wenn der Wert für "Verzögerung" + ist, wird er mit dem vorherigen Video ohne Video verknüpft.
ffmpeg.exe -y -safe 0 -f concat -i "work\concat_1.txt" -c:v copy -c:a copy -map 0:v -map 0:a "work\a-san_1280x720_con.mp4"
4.4. Fade, crop, to part Hier können Sie das Video zuschneiden und die Endzeit angeben. Wenn der Wert für "Verzögerung" ist, stellen Sie hier Einblenden ein. In ffmpeg werden die Größe nach dem Zuschneiden und die Zuschneideposition in dieser Reihenfolge angegeben. Da es jedoch persönlich etwas schwierig zu verstehen war, verwendet die Steuerdatei das Format "Zuschneiden [Zuschneideposition] [Größe nach dem Zuschneiden]". Es wird konvertiert als "Ernte (X1) x (Y1) (X2) x (Y2)" → ffmpeg "Ernte = (X2): (Y2): (X1): (Y1)". Eine der Stärken bei der Verwendung von Ruby ist, dass Sie das Format nach Ihren Wünschen selbst bestimmen können.
Der Wert von "pad =" wird aus der zugeschnittenen Größe jedes Videos berechnet. "-to" wird aus den Werten "Zeit" und "Verzögerung" in der Steuerdatei berechnet.
ffmpeg.exe -y -i "work\a-san_1280x720_cut.mp4" -vf "fade=in:0:30,crop=640:720:0:0,pad=1280:720:0:0" -to 210.0 "work\a-san_1280x720_cropped.mp4"
4.5. Mp3 out, volume part Extrahiert Nur-Ton-Dateien aus zeitgesteuerten Videos (mit -ss und -to). In ffmpeg ist 100% Volumen "1.0", in Kontrolldatei ist 100% "100". Setzen Sie "Einstellwert / 100" nach "volume =" und generieren Sie den folgenden Befehl.
ffmpeg.exe -y -i "work\a-san_1280x720_cropped.mp4" -vn -acodec libmp3lame -ar 44100 -ab 256k -af "volume=1.0" "work\a-san.mp3"
4.6. Overlay part Die individuell angepassten Videos werden per Overlay zu einem Video zusammengefasst. Berechnen Sie aus dem Wert der Ernte und generieren Sie den folgenden Befehl.
ffmpeg.exe -y -i "work\a-san_1280x720_cropped.mp4" -i "work\b-san_1280x720_cropped.mp4" -filter_complex "overlay=x=640:y=0" -an "work\out_movie.mp4"
4.7. Add audio part Geben Sie zum Schluss alle Sounds ein und Sie sind fertig. Halten Sie den MP3-Dateinamen als Array, verbinden Sie sie in der Reihenfolge mit -i, geben Sie die Größe des Arrays als Wert für "amix = input =" ein und generieren Sie den folgenden Befehl.
ffmpeg.exe -y -i "work\out_movie.mp4" -i "work\a-san.mp3" -i "work\a-san.mp3" -filter_complex "amix=inputs=2:duration=longest:dropout_transition=2" "out.mp4"
Dieses "out.mp4" ist ein fertiges Video.
Einer der Hauptnachteile bei der Eingabe von Befehlen in CUI und beim Bearbeiten von Videos besteht darin, dass Sie nicht bearbeiten können, während Sie das Timing und die Lautstärke ansehen oder anhören. Daher ist das mit der obigen Methode erstellte Video
Usw. kann angefordert werden. Um das ** nicht angepasste Video mit dem vorherigen Ergebnis ** zu beschleunigen, erstellen Sie zu diesem Zeitpunkt ein Element mit dem Namen "Überspringen" in der Steuerdatei. Wenn dies "Ein" ist, überspringen Sie die Verarbeitung dieses Videos. Ich mache es.
ffmpeg ist ein sehr ausgeklügeltes und benutzerfreundliches Tool, das ich seit langer Zeit verwende, aber es ist eine Menge Arbeit, Dutzende oder Hunderte von Befehlen einzugeben, insbesondere um Informationen in Bezug auf die Videogröße zu berechnen und einzugeben. Wird benötigt. Ich hoffe, dieser Artikel hat Ihnen geholfen, diese Bemühungen zu erleichtern.
Recommended Posts