두 개의 타임코드를 빼야 합니다. 배열에 여러 개의 타임코드가 있으며 출력은 다음과 같습니다.
**Input:**
echo ${arr3[0]}
echo ${arr3[1]}
**Output:**
00:00:22.180 --> 00:00:25.600
00:00:24.070 --> 00:00:27.790
이 예에서는 다음 수식을 사용해야 하며 00:00:25.600 - 00:00:22.180 = output into array
, 00:00:27.790 - 00:00:24.070 = output into the same array
FFMPEG에서 사용할 수 있도록 동일한 형식이어야 합니다.
또한 각 배열 항목의 첫 번째 타임코드가 필요하므로 다음과 같습니다.
00:00:22.180
00:00:24.070
ffmpeg에서도 이러한 입력을 사용할 수 있도록 다른 배열에 저장합니다.
편집하다:
나는 다음과 같이 데이터를 사용합니다
time=$(The first timecode of the array)
duration=$(Timecodes subtracted)
ffmpeg -i movie.mp4 -ss $time -t $duration -async 1 cut.mp4
답변1
샘플 데이터를 포함하는 배열 arr3이 주어지면:
declare -a arr3=([0]="00:00:22.180 --> 00:00:25.600"
[1]="00:00:24.070 --> 00:00:27.790")
배열의 각 요소를 반복하고, 시작 및 종료 시간을 제거하고, 소수 초로 변환하고, 기간을 계산한 다음, 해당 기간을 다시 ffmpeg 명령의 hh:mm:ss.sss 형식으로 변환할 수 있습니다.
# converts HH:MM:SS.sss to fractional seconds
codes2seconds() (
local hh=${1%%:*}
local rest=${1#*:}
local mm=${rest%%:*}
local ss=${rest#*:}
printf "%s" $(bc <<< "$hh * 60 * 60 + $mm * 60 + $ss")
)
# converts fractional seconds to HH:MM:SS.sss
seconds2codes() (
local seconds=$1
local hh=$(bc <<< "scale=0; $seconds / 3600")
local remainder=$(bc <<< "$seconds % 3600")
local mm=$(bc <<< "scale=0; $remainder / 60")
local ss=$(bc <<< "$remainder % 60")
printf "%02d:%02d:%06.3f" "$hh" "$mm" "$ss"
)
subtracttimes() (
local t1sec=$(codes2seconds "$1")
local t2sec=$(codes2seconds "$2")
printf "%s" $(bc <<< "$t2sec - $t1sec")
)
declare -a arr3=([0]="00:00:22.180 --> 00:00:25.600"
[1]="00:00:24.070 --> 00:00:27.790")
for range in "${arr3[@]}"
do
duration=$(subtracttimes "${range%% -->*}" "${range##*--> }")
printf "%s\n" "ffmpeg -i movie.mp4 -ss ${range%% -->*} -t $duration -async 1 cut.mp4"
done
이 codes2seconds
함수에는 HH:MM:SS.sss 형식의 입력이 필요합니다. 인수 확장을 사용하여 다양한 요소를 제거한 다음 이를 전달하여 bc
총 초로 변환합니다.
이 seconds2codes
함수는 초의 소수 부분을 취하고 변환을 반대로 하여 HH:MM:SS.sss 문자열을 생성합니다.
이 subtracttimes
함수는 두 인수를 모두 초 단위로 변환한 다음 bc
차이점을 묻습니다.
마지막 루프는 arr3의 각 요소를 반복합니다. 위 함수를 사용하여 기간을 계산한 다음(다시 매개변수 확장을 사용하여 이를 두 번 검색함) 샘플 ffmpeg
출력과 일치하는 샘플 호출을 인쇄합니다.
결과:
ffmpeg -i movie.mp4 -ss 00:00:22.180 -t 3.420 -async 1 cut.mp4
ffmpeg -i movie.mp4 -ss 00:00:24.070 -t 3.720 -async 1 cut.mp4
답변2
글쎄요, 보통 시간 코드 date
가 떠오르거든요. 가장 우아한 스크립트는 아니지만 작업을 완료합니다...
귀하의 질문에서 시작 시간과 종료 시간을 각각의 배열로 읽었으며 여기에서 해당 값을 사용하고 단계별로 진행 start
한다고 가정합니다.end
#!/bin/bash
start=00:00:22.180
end=00:00:24.070
#convert timestamps to epoch time in nano seconds
start_ns="$(date -u -d"$start" +%s%N)"
end_ns="$(date -u -d"$end" +%s%N)"
difference="$(($end_ns-$start_ns))"
#date does not read epoch time in nanoseconds,
#so it must be converted by division vith 10^9 before display
#date_diff is accurate up to full seconds
#use UTC time (-u) to avoid problems with time zones
date_diff="$( date -u -d@$((difference/1000000000)) +%H:%M:%S )"
#take care of milliseconds as remainder of division by 10^9 and correction by 10^6
ms_diff="$(( $difference%1000000000/1000000 ))"
#combine output to create desired format
echo "$date_diff"."$ms_diff"
결과
bash script.sh
00:00:01.890
모두 연속으로
echo "$(date -u -d@"$(( ($(date -u -d"$end" +%s%N) - $(date -u -d"$start" +%s%N))/1000000000 ))" +%H:%M:%S)"."$(( ($(date -u -d"$end" +%s%N) - $(date -u -d"$start" +%s%N))%1000000000/1000000 ))"
date
나노초 시간이 POSIX 표준 기능인지 는 알 수 없습니다 .