쉘 스크립트에서 숫자를 시간 형식으로 변환하는 방법은 무엇입니까?

쉘 스크립트에서 숫자를 시간 형식으로 변환하는 방법은 무엇입니까?

이렇게 영상을 10분 정도로 자르고 싶어요.

ffmpeg -i video.mp4 -ss 00:00:00 -t 00:10:00 -c copy 01.mp4
ffmpeg -i video.mp4 -ss 00:10:00 -t 00:10:00 -c copy 02.mp4
ffmpeg -i video.mp4 -ss 00:20:00 -t 00:10:00 -c copy 03.mp4

그러면 for그렇게 될 것입니다.

for i in `seq 10`; do ffmpeg -i video.mp4 -ss 00:${i}0:00 -t 00:10:00 -c copy ${i].mp4; done;

하지만 지속 시간이 1시간 미만인 경우에만 작동합니다. bash 쉘에서 숫자를 시간 형식으로 변환하는 방법은 무엇입니까?

답변1

BASH는 이 문제에 나쁘지 않습니다. 매우 강력하지만 활용도가 낮은 명령을 사용해야 합니다 date.

for i in {1..10}; do
  hrmin=$(date -u -d@$(($i * 10 * 60)) +"%H:%M")
  outfile=${hrmin/:/-}.mp4
  ffmpeg -i video.mp4 -ss ${hrmin}:00 -t 00:10:00 -c copy ${outfile}
done

date명령어 설명

date-d설정할 수 있는 플래그가 있는어느표시하려는 날짜(기본 현재 날짜 및 시간 대신)입니다. 이 예에서는 @정수 앞에 기호를 추가하여 UNIX 시간으로 설정했습니다. 이 예의 정수는 10분당 시간입니다(BASH에 내장된 계산기로 계산: ) $((...)).

+기호는 date결과가 표시되는 형식을 지정하려는 것을 나타냅니다. 우리의 경우에는 시간( %H)과 분( ) 에만 관심이 있습니다 %M.

마지막으로 -u현지 시간 대신 UTC 시간이 표시됩니다. 이 경우 UNIX 시간을 제공할 때 시간을 UTC로 지정했기 때문에 이것이 중요합니다(UNIX 시간은 항상 UTC입니다). 하나를 지정하지 않으면 숫자가 0에서 시작하지 않을 가능성이 높습니다 -u.

BASH 변수 대체 설명

date명령은 우리에게 필요한 것을 제공합니다. 그러나 파일 이름의 콜론은 문제가 있거나 표준이 아닐 수 있습니다. 따라서 ":"를 "-"로 바꿉니다. 이는 sedor cut명령을 사용하여 수행할 수 있지만 tr이는 매우 간단한 작업이므로 BASH에서 수행할 수 있는데 왜 새 하위 쉘을 생성합니까?

여기서는 BASH의 간단한 표현식 교체를 사용합니다. 이렇게 하려면 변수를 중괄호( ${hrmin})로 묶고 표준 슬래시 표기법을 따라야 합니다. 첫 번째 슬래시 뒤의 첫 번째 문자열은 검색 패턴입니다. 두 번째 슬래시 뒤의 두 번째 문자열이 대체 문자열입니다.

BASH 변수 대체 등은 다음에서 찾을 수 있습니다.http://tldp.org/LDP/abs/html/parameter-substitution.html.

답변2

조금 더 복잡하지만 bash에서 쉽게 할 수 있습니다. 아래 예는 2시간 분량의 동영상이므로 n<=11이에 따라 제한을 설정할 수 있습니다( ).

k=0; 
i=00;
for ((n=0;n<=11;n++)); do
  if [ $i -ge 60 ]; then 
    let k++; i=00; 
  fi; 
  ffmpeg -i video.mp4 -ss 0$k:$i:00 -t 00:10:00 -c copy $k$i.mp4; 
  let i+=10; 
done

echo다음 줄에 다음을 추가하면 그 기능이 무엇인지 확인할 수 있습니다 ffmpeg.

echo "ffmpeg -i video.mp4 -ss 0$k:$i:00 -t 00:10:00 -c copy $k$i.mp4";

그러면 다음이 인쇄됩니다:

ffmpeg -i video.mp4 -ss 00:00:00 -t 00:10:00 -c copy 000.mp4
ffmpeg -i video.mp4 -ss 00:10:00 -t 00:10:00 -c copy 010.mp4
ffmpeg -i video.mp4 -ss 00:20:00 -t 00:10:00 -c copy 020.mp4
ffmpeg -i video.mp4 -ss 00:30:00 -t 00:10:00 -c copy 030.mp4
ffmpeg -i video.mp4 -ss 00:40:00 -t 00:10:00 -c copy 040.mp4
ffmpeg -i video.mp4 -ss 00:50:00 -t 00:10:00 -c copy 050.mp4
ffmpeg -i video.mp4 -ss 01:00:00 -t 00:10:00 -c copy 100.mp4
ffmpeg -i video.mp4 -ss 01:10:00 -t 00:10:00 -c copy 110.mp4
ffmpeg -i video.mp4 -ss 01:20:00 -t 00:10:00 -c copy 120.mp4
ffmpeg -i video.mp4 -ss 01:30:00 -t 00:10:00 -c copy 130.mp4
ffmpeg -i video.mp4 -ss 01:40:00 -t 00:10:00 -c copy 140.mp4
ffmpeg -i video.mp4 -ss 01:50:00 -t 00:10:00 -c copy 150.mp4

답변3

간단한 수학입니다. 시간 숫자는 $((i%3600), 분 숫자는 $((i/60%60)), 두 번째 숫자는 입니다 $((i%60)). 필요한 곳에 앞에 0을 추가하려면 100을 더한 다음 앞에 있는 1. 앞에 0이 표시되는 것을 피하려면 파일 이름에도 동일한 작업을 수행하십시오.

for i in $(seq 10); do
  minutes=$((i / 60 % 60 + 100)); minutes=${minutes#1}
  seconds=$((i%60)); seconds=${seconds#1}
  i=$((i+100)); i=${i#1}
  ffmpeg -i video.mp4 -ss $((i%3600):$minutes:$seconds -t 00:10:00 -c copy ${i}.mp4
done

답변4

ffmpeg는 타임스탬프 형식으로 [HH:MM:SS]뿐만 아니라 간단한 초도 허용한다는 것을 알았습니다.

https://trac.ffmpeg.org/wiki/Seeking%20with%20FFmpeg

그래서 이렇게 쓸 수 있어요.

for i in `seq 10`; do ffmpeg -i video.mp4 -ss $((i*10*60)) -t 00:10:00 -c copy ${i].mp4; done;

관련 정보