簡體   English   中英

用於列出文件並按日期排序以在 ffmpeg 中使用的 Mac 終端命令

[英]Mac terminal command to list files and sort by date to use in ffmpeg

我正在使用 gopro 拍攝一堆視頻。 然后我想直接從 SD 卡文件夾中獲取這些視頻,並使用 FFMPEG 將它們連接成一個視頻(繞過編輯器)。

我目前能夠在我的 Mac (10.13) 上使用以下示例命令將“分章”視頻拼接在一起:

ffmpeg -f concat -safe 0 -i <(for f in /sdcardfolder/100GOPRO/GH*488.MP4; do echo "file '$f'"; done) -c copy /folder/video.mp4

這樣做的原因是 ffmpeg 命令需要一個如下所示的文本文件:

文件 '/文件夾/GH016992.MP4'
文件 '/文件夾/GH036990.MP4'
...

真正的命令是這個,它以正確的格式生成文件列表,每個file前面都有文件,可以嵌入到ffmpeg命令中:

for f in /Volumes/GoPro8/DCIM/100GOPRO/GH0*71*.MP4; do echo "file '$f'"; done

我想對此添加 2 個更改:

  1. 按日期順序列出文件(升序):我希望文件列表按日期順序排列。 但我不知道如何在for f in命令中添加-sort或其他東西。

  2. 允許一組更強大的文件匹配/過濾:現在我可以添加基本的正則表達式,如GH*488.MP4 ,或者,在增加第一個數字的章節中,像GH0[123]488.MP4這樣的東西可以得到第一個很少。 但是當我將它更改為更靈活時,如GH0[0-9]71[0-9][0-9].MP4 - 這對於匹配昨天記錄的所有文件是必要的,但在此之前沒有,命令不喜歡這個正則表達式。 它似乎只接受*

我查看了一些示例,例如https://opensource.com/article/19/6/how-write-loop-bash ,但除了列出文件之外沒有其他內容。

這歸結為一個終端命令,與 FFMPEG 並沒有真正的關系,但我希望它是有用的上下文。

我想象它會是這樣的,但這絕對行不通:

for f in (find /Volumes/GoPro8/DCIM/100GOPRO/GH0[0-9]71[0-9][0-9].MP4 -type f | sort); do echo "file '$f'"; done

我將不勝感激任何幫助! 謝謝!

更新

看起來使用 Mac 工具排序並不容易,所以我放棄並編寫了一個更簡單的 Ruby 腳本,它可以為我執行所有操作。 這並不是我上面問題的真正答案,但它是一個解決方案。

在這里,我可以輕松編寫 ffmpeg 所需的文本文件,我還可以使用名稱上的正則表達式過濾文件,過濾特定日期和大小。 然后,通過腳本,只需執行帶有 args 的 ffmpeg 命令即可連接文件。 我還可以讓它立即重新采樣文件以壓縮它(gopro 視頻很大,如果我想保存原始素材,我可以使用低得多的比特率)。

我很幸運在 Ruby 中有這個Dir.entries - 它似乎自動按日期排序? 否則我不知道如何排序。

PATH = '/Volumes/GoPro8/DCIM/100GOPRO/'
NEW_FILENAME = '/folder/new-file.mp4'
video_list = '/folder/ffmpeg-list.txt'

# create the text file
File.delete(video_list) if File.exist?(video_list)
i = 1
Dir.entries(PATH).each do |f|
    d = File.mtime(PATH + f)
    size = File.size(PATH + f)
    if f.match(/GH0.*.MP4/) && d.to_s.match(/2020-07-30/) && size.to_i < 1000000000
        puts "#{i}\t#{f}\t#{d}\t#{size}"
        File.write(video_list, "file #{PATH + f}\n", mode: "a")
        i= i+1
    end
end

command = "ffmpeg -f concat -safe 0 -i #{video_list} -c copy #{NEW_FILENAME}"

puts "executing concatenate..."
puts command
system(command)

列出並排序文件並迭代讀取每個條目:

find /Volumes/GoPro8/DCIM/100GOPRO/ \
  -name 'GH0[0-9]71[0-9][0-9].MP4' \
  -type f \
  -printf '%A@\t%p\0' | sort -z -k1n | cut -z -f2- |
  while IFS= read -r -d '' f; do
    echo "$f"
  done

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM