여러 파일에 대한 노틸러스 스크립트(ffmpeg)

여러 파일에 대한 노틸러스 스크립트(ffmpeg)

저는 프로그래밍 배경 지식이 거의 또는 전혀 없으며 여러 비디오 파일에서 오디오를 추출하기 위한 일괄 처리 프로세스를 만들어야 합니다. 실행은 Nautilus의 스크립트 폴더에 bash .sh로 저장된 Nautilus/Gnome 파일의 상황에 맞는 메뉴를 통해 수행됩니다. 다음 코드는 파일 1개에 대해 작동하지만 여러 파일을 선택할 때는 작동하지 않습니다. 코드가 작동하도록 수정하는 데 도움을 줄 수 있는 사람이 있나요?

#!/bin/bash

FILENAME=$(echo $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS | sed -e 's/\r//g')
FILENAME2=$(echo "$FILENAME" | cut -f 1 -d '.') 

    ffmpeg -i "${FILENAME}" -vn -acodec pcm_s16le -ac 2 -ar 48000 "${FILENAME2}".wav

    # finished message box
    zenity --info --title "Procesing completed" --text "${FILENAME2}.wav at 48kHz has been generated." --width=700

답변1

이 스크립트를 사용하면 테스트할 수 없지만 ffmpeg작동할 것입니다.


#!/bin/bash

{

readarray FILENAME <<< "$(echo -e "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" | sed -e 's/\r//g')"

echo -e "Logs: $(date)\n" > ~/Desktop/data.txt

for file in "${FILENAME[@]}"; do
    
    file=$(echo "$file" | tr -d $'\n')
    echo "Current file: $file" >> ~/Desktop/data.txt
    ffmpeg -i "$file" -vn -acodec pcm_s16le -ac 2 -ar 48000 "${file%.*}.wav"
    zenity --info --title "Procesing completed" --text "${file%.*}.wav at 48kHz has been generated." --width=700
done


} 2>~/Desktop/ffmpeg.logs

위의 코드는 a가 처리될 때 zenity마다 mp4메시지를 인쇄 합니다. 그러나 모든 파일이 처리될 때 메시지를 표시하려면 다음 스크립트를 사용할 수 있습니다.

#!/bin/bash

{

readarray FILENAME <<< "$(echo -e "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" | sed -e 's/\r//g')"

echo -e "Logs: $(date)\n" > ~/Desktop/data.txt

for file in "${FILENAME[@]}"; do
   
    file=$(echo "$file" | tr -d $'\n')
    echo "Current file: $file" >> ~/Desktop/data.txt
    ffmpeg -i "$file" -vn -acodec pcm_s16le -ac 2 -ar 48000 "${file%.*}.wav"
done

zenity --info --title "Procesing completed" --text "$( printf "%s.wav\n" "${FILENAME[@]%.*}") at 48kHz has been generated." --width=700

} 2>~/Desktop/ffmpeg.logs

이 스크립트를 사용하는 것이 좋습니다. 실패한 파일과 성공적으로 생성된 파일을 감지하는 기능으로 인해:

#!/bin/bash

{

readarray FILENAME <<< "$(echo -e "$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS" | sed -e 's/\r//g')"

echo -e "Logs: $(date)\n" > ~/Desktop/data.txt
okFiles=()
errFiles=()

for file in "${FILENAME[@]}"; do
    
    file=$(echo "$file" | tr -d $'\n')
    echo -e "\n===========================" >> ~/Desktop/data.txt
    echo "Current file: $file" >> ~/Desktop/data.txt
    ffmpeg -i "$file" -vn -acodec pcm_s16le -ac 2 -ar 48000 "${file%.*}.wav" && {
        okFiles+=("${file%.*}.wav")
        :
    } || {
        
        errFiles+=("${file%.*}.wav")
    }
done

if [[ ${#okFiles[@]} -gt 0 ]]; then
    zenity --info --title "Procesing completed" --text "$(printf '%s\n' ${okFiles[@]})\n at 48kHz have/has been generated." --width=700
fi

if [[ ${#errFiles[@]} -gt 0 ]]; then
    zenity --info --title "Error while processing some files" --text "Following files:\n$(printf "%s\n" "${errFiles[@]}")\ncould not be generated." --width=700
fi

} 2>~/Desktop/ffmpeg.logs

에 대한:

{
  code
  code
} 2>~/Desktop/ffmpeg.logs

각 파일을 처리할 때 문제를 감지하는 데 사용합니다. 예를 들어 일부 파일에서 오류가 발생하면 ffmpeg해당 경로 내의 로그를 확인할 수 있습니다.~/Desktop/ffmpeg.logs

그런데, 처리하는 모든 파일을 스크립트가 호출되는 위치가 아닌 특정 경로에 있도록 하려면 다음을 수행할 수 있습니다(전 readarray).

{
  cd ~/Audios/path/to/dir #the path you want can be placed here
  readarray ...
  code
} 2>~/Desktop/ffmpeg.logs

FILENAME2마지막으로, 내가 사용한 이후로 더 이상 필요하지 않다는 것을 알 수 있습니다 "${file%.*}.wav"(참조Bash 매개변수 설명).

관련 정보