오디오 파일 폴더를 단일 파일로 변환하는 방법(여러 폴더에 대해 반복)?

오디오 파일 폴더를 단일 파일로 변환하는 방법(여러 폴더에 대해 반복)?

나는 다양한 시리즈의 여러 라디오 드라마를 가지고 있습니다. 일부는 이미 단일 트랙이고 일부는 다중 트랙입니다. 나는 모든 것이 단일 트랙이기를 바랍니다. 다시 인코딩하는 것은 마음에 들지 않습니다. 실제로 모바일 장치로 스트리밍하고 opus 출력을 선호합니다.

이것은 개별 오디오북 폴더에서 mp3를 opus로 변환하는 트릭을 수행하는 것 같습니다.

ffmpeg -i "concat:$(ls *.mp3 | tr '\n' '|')" -acodec opus test.opus

이제 변환하고 싶은 다중 트랙 라디오 쇼가 많이 있습니다. 사용 find하거나 결과를 연결할 수 있는 함수를 정의하고 싶습니다 ls.

나는 이것의 변형을 찾아 헤매고 있습니다.

function audioconcat { folder=$1; iformat=$2; oformat=$3; echo $folder; echo $iformat; echo $oformat; ffmpeg -i \'concat:$(find "$folder" -name *.$iformat | tr '\n' '|' | tr ' ' '\ ' | head -c -1)\' -acodec $oformat \'$folder.$oformat\'; }

따라서 폴더 내에서 주어진 입력 형식의 파일을 찾아서 ffmpeg 연결에 넣고 스트림을 주어진 출력 형식으로 인코딩한 다음 폴더 이름을 사용하여 단일 파일로 저장하는 것이 아이디어입니다.

그러나 저는 항상 공백 및/또는 중첩된 함수 호출에 문제가 있는 것 같습니다.

기능을 수정하려면 어떻게 해야 합니까? 아니면 위의 변환을 수행하는 더 좋은 방법이 있습니까?

답변1

코드에서 개선될 수 있는 몇 가지 안티 패턴을 시연했습니다. 바라보다왜 네가해서는 안 된다ls(1)의 출력을 구문 분석합니다.. ls명령의 출력을 구문 분석할 필요가 없으며 tr명령 및 find.

기본 쉘에서 제공하는 glob 옵션을 더 잘 사용하는 것이 좋습니다. 귀하의 경우에는 shell 이어야 합니다 bash.

$(ls *.mp3 | tr '\n' '|')이 코드는 아래와 같이 파일 글로빙에 제공되는 옵션을 사용하여 훌륭하게 작성할 수 있습니다.bash

shopt -s nullglob
mp3FileList=(*.mp3)

이 확장 셸 옵션은 배열을 채울 때 빈 glob 결과를 처리하는 대신 건너뛰도록 하기 위해 활성화됩니다. cd해당 폴더로 가서 다음을 수행 해야 합니다 . |배열 뒤의 마지막 항목도 원래 목록에 포함시켰기 때문에 기록해 두세요 . 필요없으시면 삭제하세요.

fileString=$( IFS='|'; echo "${mp3FileList[*]}|" )

|위의 변수에는 이제 개별적으로 형식화된 파일 목록이 포함되며, |이는 최종적으로 명령에 전달될 수 있습니다 ffmpeg.

ffmpeg -i "concat:${fileString}" -acodec opus test.opus

여러 옵션을 스크립트에 전달하는 것과 관련된 두 번째 요구 사항입니다. 이 스크립트를 확장하여 다음을 수행할 수 있습니다.

audioConcat() {
    (( "$#" < 3 )) && { printf 'insufficient arguments supplied' >&2; exit 1 ; }
    cd "$1" || { printf 'unable to navigate to target\n' >&2; exit 2 ; }

    shopt -q nullglob; nullglob_set=$?
    ((nullglob_set)) && shopt -s nullglob

    local fileList
    local fileString

    fileList=(*."${2}")

    if (( ${#fileList[@]} )); then
        fileString=$( IFS='|'; echo "${fileList[*]}" )
        ffmpeg -i "concat:${fileString}" -acodec "$3" "$1.$3"  
    else
        printf 'unable to find files of extension %s\n' "$2" >&2
        exit 3 
    fi

    ((nullglob_set)) && shopt -u nullglob      
}

함수를 호출할 때 매개변수를 다음과 같이 전달하십시오.

audioConcat '/path/to/mp3files/' 'mp3' 'opus'

ffmpeg위 함수의 행을 주석 처리하고 변수가 생성되었는지 확인하는 것이 좋습니다.~처럼실제 명령을 호출하기 전에 필요합니다. 또한 |파일 목록에 후행이 필요한지 확인하십시오.

함수에 사용되는 구조에 대한 간략한 요약

  1. 경로 이름 확장 중에 설정된 옵션은 nullglob빈 글로브 확장을 방지합니다. 즉, .mp3파일을 찾을 수 없으면 확장되지 않은 글로브 대신 확장 시 배열이 비어 있게 됩니다.
  2. $(IFS='|'; echo "${mp3FileList[*]})별도의 형식으로 출력을 인쇄하는 멋진 방법입니다 |. 서브셸(입력 필드 구분 기호)을 수정하므로 IFS전역적으로 수정되지 않습니다. 배열 확장은 [*]문자열을 IFS설정된 값과 연결합니다.

일부 기타 품목. 고려해야 할 사항: - exit함수에서 from을 사용하면 실제로는출구함수를 실행 중인 현재 셸입니다. 명령줄에서 사용할 때는 권장되지 않지만 적절한 인터프리터 she-bang 설정을 사용하여 스크립트에서 실행할 때 더 적합합니다. 이 경우 스크립트를 실행하기 위해 시작된 하위 쉘에서 종료됩니다. 명령줄에서 더 자주 사용하려면 exit호출을 return.

관련 정보