ffmpeg : 무음으로 부품 제거 : 비디오의 여러 부분을 효율적으로 제거하십시오. -2 -ss 12.520000 -to 12.630000 buff.mp4 ffmpeg

오디오가 없거나 거의없는 비디오의 일부를 제거하려고합니다. 이것을 위해 저는 대담성을 사용합니다 ( 분석 -> 사운드 파인더 ) 그리고 수출 라벨 트랙 . 결과는 다음과 같습니다.

0.000000    5.170000    1
12.520000   12.630000   2
14.400000   15.660000   3
17.430000   22.150000   4
...

이 정규식 : ([\d]+.[\d]{6})\t([\d]+.[\d]{6})\t([\d]+)\n & gt; ffmpeg -i VL1.mp4 -strict -2 -ss \1 -to \2 buff.mp4\nffmpeg -f concat -i <(echo "file '/home/rene/videotest/output.mp4'\nfile '/home/rene/videotest/buff.mp4'") -c copy output2.mp4\nrm buff.mp4\nmv output2.mp4 output.mp4\n 일부 수동 편집을하면 다음과 같이 표시됩니다.

#!/bin/bash

ffmpeg -i VL1.mp4 -strict -2 -ss 0.000000 -to 5.170000 output.mp4
ffmpeg -i VL1.mp4 -strict -2 -ss 12.520000 -to 12.630000 buff.mp4
ffmpeg -f concat -i <(echo "file '/home/rene/videotest/output.mp4'
file '/home/rene/videotest/buff.mp4'") -c copy output2.mp4
rm buff.mp4
mv output2.mp4 output.mp4
ffmpeg -i VL1.mp4 -strict -2 -ss 14.400000 -to 15.660000 buff.mp4
ffmpeg -f concat -i <(echo "file '/home/rene/videotest/output.mp4'
file '/home/rene/videotest/buff.mp4'") -c copy output2.mp4
rm buff.mp4
mv output2.mp4 output.mp4
ffmpeg -i VL1.mp4 -strict -2 -ss 17.430000 -to 22.150000 buff.mp4
ffmpeg -f concat -i <(echo "file '/home/rene/videotest/output.mp4'
file '/home/rene/videotest/buff.mp4'") -c copy output2.mp4
rm buff.mp4
mv output2.mp4 output.mp4
...

이것은 꽤 잘 작동하고 파일을 얻습니다. output.mp4 내가 원하는 부분 만 포함하고 있습니다.

불행히도 이것은 매우 느립니다 – 그리고 나는 그것이 모든 부분에 대해 파일이 있기 때문에 내 HDD를 파괴 할까 두려워합니다. buff.mp4 생성 된 모든 기존 파트와이 짧은 클립을 포함하는 새 파일이 HDD에 기록되고 기존 파트가 포함 된 이전 파일이 삭제됩니다. 클립의 대부분은 정말 짧기 때문에 (보통 몇 초 미만) 내 아이디어는 파일을 쓰지 않는 것이 었습니다. buff.mp4 HDD로 보내지 만 대신 ffmpeg로 이것을 통과시킵니다. < (그래서 RAM에 보관 하시겠습니까?). 두 번째로 추가 할 내용은 output.mp4 매번 파일을 다시 쓰지 않아야합니다.

불행히도 두 가지 모두 ffmpeg 및 bash에 대한 지식은 일반적으로 너무 작습니다. 누군가 나를 도울 수 있었습니까?

내가 수동 정규식 물건없이 멋진 스크립트를 작성할 수 있어야합니다. 그리고 물론 나중에 이것을 출판 할 것입니다.



답변

내가 지금 사용하는 솔루션은 목록 입력 파일을 스캔하고이 정보에서 “무음”스 니펫이있는 작은 파일을 만듭니다. 모든 파일이 파일에 기록됩니다. temp 올바른 순서로. 이 작업이 완료되면 부품이 병합되고 임시 파일이 정리됩니다. 이것은 아니 매우 빠릅니다. 90 분짜리 클립의 총 약 1000 회분은 i7 프로세서, 10GB RAM에서 약 5 시간이 걸립니다.

나는 짐작한다. ffmpeg 필터가있는 솔루션 훨씬 더 빠를 것입니다. 그러나 그 순간은 너무 복잡했습니다. 또 다른 해결책은 이것 일 수 있습니다. 코드 예제 . 둘 다 아마도 tmp 파일 (헤더, 파일 쓰기 등)을 만들지 않기 때문에 더 효율적일 것입니다.

어쨌든, 현재 작업 코드는 다음과 같습니다.

#!/bin/bash
echo "">temp

# File or Directory selection menu with dialog
function fileDialog {
    read -p "$2: " fileselection
    echo "You've selected $fileselection"
}


WORKPATH=$(pwd)

echo "Arbeitsverzeichnis: $WORKPATH"

fileDialog "$WORKPATH" "Select original Video-File"
INFILE=$fileselection
ff=$(ffmpeg -i "$INFILE" 2>&1)
d="${ff#*Duration: }"
LENGTH="${d%%,*}"
echo "Arbeitsverzeichnis: $WORKPATH"
echo "Videodatei: $INFILE"
echo "Gesamtvideolänge $LENGTH"

fileDialog "$WORKPATH" "Select Label-List-File (exported from Audacity)"
LABELFILE=$fileselection
NUMLINES=$(awk 'END { print NR }' "$LABELFILE")
clear
echo "Arbeitsverzeichnis: $WORKPATH"
echo "Videodatei: $INFILE"
echo "Gesamtvideolänge $LENGTH"
echo "Sequence-Label-Datei: $LABELFILE"
echo $NUMLINES lines/sequences found in \'$LABELFILE\'
echo ""
echo "Start processing..."
awk '{d=sprintf("echo Processing Part "NR"/'"$NUMLINES"' named "$3" from "$1"s to "$2"s..."); system(d); s=sprintf("ffmpeg -hide_banner -loglevel panic -accurate_seek -y -i '"$INFILE"' -strict -2 -ss "$1" -to "$2" tmp-"NR".mp4>/dev/null"); system(s); p=sprintf("echo \"$(cat temp)\nfile '"$WORKPATH"'/tmp-"NR".mp4\">temp"); system(p);}' "$LABELFILE"

echo "Merging all "$NUMLINES" parts."
ffmpeg -f concat -i temp -c copy "short-$INFILE.mp4"

echo "Cleaning up..."
rm tmp-*.mp4
rm temp
rm "$INFILE"

두 가지 더 작은 일을해야합니다 : 현재 이것은 mp4로 비디오를 변환합니다. 이것은 실제로 필요하지 않으며 아마 단지 CPU 시간의로드를 필요로합니다.