顯示具有 FFmpeg 標籤的文章。 顯示所有文章
顯示具有 FFmpeg 標籤的文章。 顯示所有文章

2024年11月10日 星期日

開發 yt-dlp 應用的好幫手 cli_to_api.py

2024年11月10日 星期日

無論是 youtube-dl 或是後繼的分支 yt-dlp 都是用來下載網站影音的好工具,各大知名的影音網站都支援,真的是「超級強」,唯一的缺點它是屬於命令列的工具(對不畏懼指令的人,反而更能把 yt-dlp 的特色完全發揮)。如果不想面對指令,我也弄了一個只要填填資料就能用的,放在這篇文章中,可以試試看:

上面這個小工具是在 Google Colab 的虛薿機以 Python 來處理表單資料,再使用 yt-dlp 的模組來執行影音下載及後續的處理,

關於 yt-dlp 在下指令時,可用的功能選項語法,可以參考官方的說明:

模組中的應用方式可以參考 yt-dlp 的官方說明:

一開始,我以為就是將命令模式用的參數套到模組中就好了,很簡單嘛!哈~真的是太單純了!yt-dlp 的參數包羅萬向,有的參數是用在前端,有的參數是用在後端;同一個功能,名稱及所屬的階層亦不同。感覺直接下指令好像單純一點。

例如,下載影片後,只想儲存 mp3 聲音檔(如果使用預設工具,它是在最後時以 FFmpeg 來進行轉檔),在命令列中使用的是這樣的參數:

--extract-audio --audio-format mp3

但是在 Python 中使用 yt_dlp 模組時,最少必須在設定中使用:

'postprocessors': [{
    'key': 'FFmpegExtractAudio',
    'preferredcodec': 'mp3',
}]

哈!當初為了這個卡關很久,因為一開始,要嘛去搜尋別人的討論或心得;不然就是直接追 yt-dlp 的原始碼。有收穫,但是花了很多時間。

重點來了!昨天在這個網頁中找到了寶:

裡面提到了有一個名為「cli_to_api.py」的工具:

我們只要將在下 yd-dlp 命令時用的參數給 cli_to_api.py ,它就會提供轉換的建議,可以輕鬆地應用在 Python 中。例如,我輸入:

python cli_to_api.py --extract-audio --audio-format mp3

它就給我這樣的內容:

The arguments passed translate to:

{'final_ext': 'mp3',
 'format': 'bestaudio/best',
 'postprocessors': [{'key': 'FFmpegExtractAudio',
                     'nopostoverwrites': False,
                     'preferredcodec': 'mp3',
                     'preferredquality': '5'}]}

Combining these with the CLI defaults gives:

{'extract_flat': 'discard_in_playlist',
 'final_ext': 'mp3',
 'format': 'bestaudio/best',
 'fragment_retries': 10,
 'ignoreerrors': 'only_download',
 'postprocessors': [{'key': 'FFmpegExtractAudio',
                     'nopostoverwrites': False,
                     'preferredcodec': 'mp3',
                     'preferredquality': '5'},
                    {'key': 'FFmpegConcat',
                     'only_multi_video': True,
                     'when': 'playlist'}],
 'retries': 10}

真的是太令人感動了!愛死開源的社群了,讓人功力馬上大增!

另一個例子,如果想讓 yt-dlp 可以將有分章節的 YouTube 影片,下載後一個章節儲存一個檔案,命令列可以使用這個參數:

--split-chapters

使用  cli_to_api.py 來轉換一下:

The arguments passed translate to:

{'postprocessors': [{'force_keyframes': False, 'key': 'FFmpegSplitChapters'}]}

Combining these with the CLI defaults gives:

{'extract_flat': 'discard_in_playlist',
 'fragment_retries': 10,
 'ignoreerrors': 'only_download',
 'postprocessors': [{'force_keyframes': False, 'key': 'FFmpegSplitChapters'},
                    {'key': 'FFmpegConcat',
                     'only_multi_video': True,
                     'when': 'playlist'}],
 'retries': 10}

關鍵的設定是:

{'postprocessors': [{'force_keyframes': False, 'key': 'FFmpegSplitChapters'}]}

真是要命!害我鬼打牆,一直以為用「'split_chapters': True」,然後下指令明明成功了,在 Python 中,就是沒效果。

另外,以 chapters 儲存為什麼檔名的語法,順便筆記一下,命令列的參數:

-o "chapter:%(title)s-%(section_number)02d-%(section_title)s.%(ext)s"

用在 embedding 時:

'outtmpl': {'chapter': '%(title)s-%(section_number)02d-%(section_title)s.%(ext)s'}

怕檔名有用到特列的字,保險一點,還可以再加上 --windows-filenames 參數:

'windowsfilenames': True

有了  cli_to_api.py 這個小工具,真的是幫了大大的忙,讓人可以更體驗到 yt-dlp 這工具的強大。

相關連結


2023年3月30日 星期四

Toots : yt-dlp 下載 Youtube 或是其它網站的影音

2023年3月30日 星期四

每次別人問我如何下載 Youtube 影片,或是如何將 YouTube 影片下為 MP3?我唯一推薦使用的就是 youtube-dl (目前活躍發展的版本稱為 yt-dlp ),原因無他,它實在太強大了,不只可以下載 Youtube 的影片,很多知名網站的影音都可以下載。

▋ 支援哪些網站的下載?

yt-dlp 不是只能下載 YouTube 的影片哦!

像 Facebook 的影片、Twitter (X) 的影片 ...... 也可以,實在太多了,有興趣可以去 yt-dlp 專案看,傳送門在此:

它的小缺點是,官網提供的 yt-dlp 必須在命令列中輸入指令;如果想把影片轉為 mp3,還必須另外安裝 ffmpeg。

哈!一般人光看到「打指令」、「安裝」...... 就倒退 N 步了;所以有一些披著圖形界面,然後在背後使用 yt-dlp 的工具就應運而生。不過,如果要將 yt-dlp 的強大發揮到極至,打命令還是最有效率的。對指令有興趣,可以參考這個:

▋ 我來安裝,您來填寫表單下載影音

「yt-dlp 是以下指令的方式來使用」,太可怕了!!

好啦!不怕~不怕~~我在 Google Colab 中建好了會自動安裝 yt-dlp ,及自動下載影音的程序,您只要在表單中填寫要下載的影片網址、勾選要下載 mp4 影片,還是 mp3 音檔 ......,最後按一下執行鈕  ,不用自己面對指令了。

[圖1] 中的「url」的輸入欄位,是用來輸入想下載的影音網址,以 YouTube 來說,可以輸入單一影片的網址,或是播放清單的網址;選取完想要下載的是 mp4 (影片),或是 mp3 (純聲音),再按一下「執行」  的圖示,就會自動安裝並依設定執行程式,剩下的就是等待 Colab 幫我們將影音處理好,然後下載囉!

這個 Google Colab 中的 yt-dlp 執行時是在網頁瀏覽器中操作,所以可以在桌機、筆電、手機或是平板的網頁瀏覽器中執行。不過行動裝置因為有自動鎖定螢幕的機置,如果處理的時間較久,可能會因為自動鎖定螢幕而中斷程式的執行,影片比較大的時候,要注意鎖定螢幕的問題。

[圖1] Colab 上的 yt-dlp

▋ yt-dlp 影音下載工具的網址

下面這個短網址是放在 Google Colab 中的 yt-dlp :

▋ 使用方法

使用的方法很簡單,

  1. 打開前述的網址以後,進入 Colab 的頁面。
  2. 在「影音檔的網址」的欄位中填入影音所在的網址,例如: YouTube 影片網址、Facebook 有公開分享的網址 ......。
  3. 選取要輸出的格式。
  4. 設定其它選項。
  5. 都設定好了,就按左側有個三角形的圖示(  ),啟動安裝及下載的程序。

影片如果檔案較大者,可能要花一點時間,才能將影音檔案由 Google Colab 下載到自己的電腦,稍安勿躁,喝杯茶,輕鬆一下吧~~

▋ 下載失敗了嗎?

🌏 如果遇到無法下載的情形,首先要確認影片的來源是否為公開給任何人都可以看的,因為放在 Google Colab 中的 yt-dlp 是以「匿名」的方式去擷取影音的,並不是用您的身份,所以必須是公開給任何人的影音,才能抓得到。

 另外,如果是遇到錯誤訊息中有「Sign in to confirm you’re not a bot」,或是「403 Forbidden 」,可以參考這則文:

🐜 或是還有其它問題,請在本則文章最下方的留言區留言。




✂ ----------【分隔線】----------


✂ ----------【以下請忽略】----------



yt-dlp 合併為 mp4 的指令使用與除錯筆記

以下純屬個人的筆記,如果只是要用前述的工具,這部份建議略過不看,以免頭暈 ^_^ 。

在使用 yt-dlp 時,發現它和原生的 youtube-dl 顯著不同的地方。以預設值,直接下載 YouTube 的影片,它會將影片及聲音合併為 .mkv 格式的檔案;查了一下參數,照說使用「--merge-output-format mp4」可以將影音合併為 .mp4 的,但是一切並沒有如預期那麼容易,在我的電腦上,或是在 Google Colab 的環境中,都會出現類似這樣的錯誤訊息:

[youtube] wSBXfzgqHtE: Downloading android player API JSON
[info] wSBXfzgqHtE: Downloading 1 format(s): 248+251
[dashsegments] Total fragments: 6
[download] Destination: test3.f248.webm
[download] 100% of   55.29MiB in 00:00:25 at 2.14MiB/s
[dashsegments] Total fragments: 1
[download] Destination: test3.f251.webm
[download] 100% of    4.83MiB in 00:00:02 at 2.20MiB/s
[Merger] Merging formats into "test3.mp4"
ERROR: Postprocessing:   Stream #1:0 -> #0:1 (copy)

從訊來看,影片有下載回來 (248.webm),聲音有下載回來(251.webm),問題出在最後合併為 .mp4 的階段。

如果我們在 yt-dlp 的指令中再加上「-v」,可以更清楚問題點。摘錄最關鍵的錯誤訊息:

Input #0, matroska,webm, from 'file:test3.f248.webm':
  Metadata:
    encoder         : google/video-file
  Duration: 00:04:48.66, start: 0.000000, bitrate: 1606 kb/s
    Stream #0:0(eng): Video: vp9 (Profile 0), yuv420p(tv, bt709), 1920x1080, SAR
 1:1 DAR 16:9, 29.97 fps, 29.97 tbr, 1k tbn, 1k tbc (default)
Input #1, matroska,webm, from 'file:test3.f251.webm':
  Metadata:
    encoder         : google/video-file
  Duration: 00:04:48.68, start: -0.007000, bitrate: 140 kb/s
    Stream #1:0(eng): Audio: opus, 48000 Hz, stereo, fltp (default)
[mp4 @ 0000000000146400] track 1: codec frame size is not set
[mp4 @ 0000000000146400] opus in MP4 support is experimental, add '-strict -2' i
f you want to use it.

Could not write header for output file #0 (incorrect codec parameters ?): Experi
mental feature

如果照上面紅色訊息中的指示,將「-strict -2」加在 ffmpeg 的參數中,的確就可以解決問題了。再去搜尋一下「opus in MP4 support is experimental, add '-strict -2' i f you want to use it.」,原來問題在 ffmpeg 的版本,我電腦中的 ffmpeg 和 Google Colab 環境中使用的 ffmpeg,都不是最新版,不加「「-strict -2」」,它就無法將「.webm」的聲音檔合併到 .mp4 中。如果將 ffmpeg 更新為最新的版本,ffmpeg 會自動幫忙處理好,yt-dlp 就不會因無法合併 .webm 產生錯誤而中斷了。

如果不更新 ffmpeg 也可以解決被 .webm 聲音檔打斷合併為 .mp4 影片的問題嗎?

既然知道是 .webm 聲音檔在作祟,那我們就限定聲音使用 mp4 可接受的聲音檔就好了,例如指定使用「m4a」格式,例如:

yt-dlp  -f "bv+ba[ext=m4a]/b" --merge-output-format mp4 https://www.youtube.com/watch?v=dQomed4X80U

上面的關鍵在「-f "bv+ba[ext=m4a]/b"」裡的「ba[ext=m4a]」,它指定使用音質最好的聲音檔,而且指定要使用「m4a」格式的,這樣一來,影片和聲音合併為 .mp4 時就不會有問題了。

有沒有更簡單的?

當然有,像這樣:

yt-dlp  -S "ext" --merge-output-format mp4 https://www.youtube.com/watch?v=dQomed4X80U

加上「-S "ext" 」的話,根據 yt-dlp 參數範例的說明,它就會用附檔名來決定選用的優先順序:

  • 影片的優先順序: mp4 > mov > webm > flv 
  • 聲音的優先順序: m4a > aac > mp3 ...

「m4a」是會被優先選用的,完全符合我們合併為 .mp4 時的需求。

在 Colab 中將除錯的歷程記錄在下列筆記本中:

可以實際觀察到 Colab 目前的 ffmpeg (ver. 4.2.7) 和 yt-dlp (ver. 2023.03.04) 的錯誤訊息及可行的參數運用方法。

相關連結


2022年8月11日 星期四

FFmpeg : 修改 .srt 字幕檔內的時間

2022年8月11日 星期四

 FFmpeg 可以用來幫影片加字幕,那可以編輯字幕檔內,各段文字出現的時間嗎?

我找到了一部影片的 .srt 字幕檔,但是發現它的時間比影片晚了 15點多秒鐘,找了一下資料,利用 FFmpeg 的「 -itsoffset」參數,就可以控制字幕出現的時間。例如

ffmpeg -itsoffset 10 -i subtitle_file.srt  output.srt

它就會將 .srt 中的所有時間,通通加上10秒鐘,然後輸出到 output.srt。

如果時間用負數,例如:

ffmpeg -itsoffset -10 -i subtitle_file.srt  output.srt

它就會將 .srt 中的所有時間,通通提早 10 秒鐘。

哈!這樣是不是很棒!

不過,經過實際操作,「 -itsoffset」參數使用負數的時間,必須要「夠減」才行。像我的字幕檔中的內容大概像這樣:

1
00:00:01,000 --> 00:00:06,000
== xxx xxxx==

2
00:00:15,065 --> 00:00:16,266
xxxxxx?

3
00:00:16,266 --> 00:00:18,502
xxxxxxxxxxx

我想將每一行字幕,通通提早 16 秒鐘,就執行以下的指令:

ffmpeg -itsoffset -16 -i subtitle_file.srt  output.srt

第 1~2 行字幕因為不夠減,就無法正確的顯示了。

因此我做了兩個修正:

  • 改成通通提早 15 秒鐘就好(這樣子第2行字幕之後的,就不會有時間不足的情形)。
  • 手動修改 .srt 中的第一行字幕的時間為:
    00:00:15,000 --> 00:00:15,000

這樣子就可以使用底下提早 15 秒鐘的轉換指令:

ffmpeg -itsoffset -15 -i subtitle_file.srt  output.srt

實作的結果,還不錯!影片的語音跟字幕是對得上的。

相關文章


2022年6月4日 星期六

ffplay : 播放目錄中的所有影音檔

2022年6月4日 星期六

 ffplay 是 FFmpeg 套件中的一個影音播放器,沒有複雜的功能,哈!我喜歡它的精簡,不過似乎沒有支援播放清單的功能。沒關係,有人跟我有一樣的需求,找到這個討論串:

裡面看到了幾個 ffplay 的參數:

  • -autoexit : 播放完自動結束程式
  • -nodisp : 不顯示播放器

再加上 ffmpeg 也有的參數,「-hide_banner」或「-v quiet」,可以不顯示播放器的詳細資訊,畫面就更乾淨了。

所以用 ffplay 來播放 mp3 ,如果只播放一次就結束,指令可以這樣:

ffmpeg -hide_banner -autoexeit -nodisp XXX.mp3

想讓畫面更精簡就:

ffmpeg  -v quiet -autoexeit -nodisp XXX.mp3

需要更多選項,可以參考官網文件:

播放清單呢?

假設要播放的 mp3 都放在一個資料夾中了,在 Windows 中,就可以先切換到該資料夾中,結 FOR /F 的指令,像這樣:

FOR  /F %f IN ('dir /b') DO ffplay -autoexit -nodisp -v quiet "%f"

上面用「dir /b」來取得該目前目錄的所有檔案清單,然後一個個檔名指定給 %f。

「DO」後面就是 ffplay 的指令了,只是檔名的參數用「 %f」。

其它非 Windows 的系統的話,也是有相對應的 shell 指令可以用的。

哈!滿有意思的。


ffplay : Windows 中無法播放 mp3

FFmpeg 中,除了 ffmpeg 以外,還有 ffprobe 和 ffplay 兩個很好用的工具,之前遇過在 Windows 中使用 ffplay 來播放影片時,看得到畫面,卻沒有聲音。因為還有 VLC Player 可以用,所以也就沒管它;這兩天想直接在程式中,下指令來呼叫 ffplay 播放 mp3,當然還是不能用。

不過,這回有認真看錯誤訊息了,大概長這樣:

SDL_OpenAudio (1 channels, 22050 Hz):  WASAPI can't initialize audio client: CoInitialize

查了一下:

只要在 Windows 中設定一下環境變數「SDL_AUDIODRIVER」,讓播放器知道要用哪一個聲音的驅動程式即可解決。例如在執行 ffplay 之前,執行這一行:

set SDL_AUDIODRIVER=directsound

如果常用,就在 Windows 的系統中設定環境變數,這樣就可以一勞永逸了。


2022年5月30日 星期一

FFmpeg : 更改 mp3 的速度

2022年5月30日 星期一

 利用之前這篇「雄 : 透過 Colab 批次下載 FreeTTS mp3」下載回來的全成語音,有些聲音語速滿快的,雖然我們可以在播放時,再透過程式來調整,總覺得乾脆批次處理,一次解決比較俐落。因此,強大的 ffmpeg 又可以出場了!

我們可以使用 ffmpeg 的 atempo 來調整影音的速度:

例如:

ffmpeg -i source.mp3 -filter:a "atempo=0.75" output.mp3

上面的指令,可以將 source.mp3 的速度變成原來的 0.75 倍後,輸出成 output.mp3。

那如果想結合之前「雄 : FFmpeg : 在聲音檔前面加一小段靜音」中的 adelay filter ,在 mp3 前面加上 0.5 秒的靜音,例如:

ffmpeg -i source.mp3 -af "adelay=500|500" output.mp3

是不是直接這樣子,加分號串接?(ffmpeg 要用多種效果時用分號)

ffmpeg -i source.mp3 -filter:a "atempo=0.75; adelay=500|500" output.mp3

哈!要是像上面用,會出現類似底下的錯誤訊息啦!

Simple filtergraph 'atempo=0.75; adelay=500|500' was expected to have exactly 1 input and 1 output. However, it had >1 input(s) and >1 output(s). Please adjust, or use a complex filtergraph (-filter_complex) instead.
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #0:0
Conversion failed!

錯誤訊息中有個關鍵字「-filter_complex」,就照這個方向試著改改看,變成:

ffmpeg -i source.mp3 -filter_complex "atempo=0.75 [temp]; [temp] adelay=500|500" output.mp3

有改變的部份,主要是使用 ffmpeg 的 Filtergraph

簡單的說明一下,source.mp3 先用 atempo 改變速度,處理完的結果用 [temp] 這個標籤代表;接著 [temp] 再用 adelay 在最前上加上 0.5 秒的靜音;最後輸出到 output.mp3。

這部份的技巧在「雄 : FFmpeg : 影片剪接與加馬賽克」中的影片處理中也使用過。

知道如何用 ffmpeg 來同時更改 mp3 的速度及在最前面加上一小段靜音,接下來只要再結合批次檔,就可以一次處理整個資料夾的語音檔囉!

相關文章


2022年5月24日 星期二

youtbue-dl : 下載 ffmpeg 無法下載的串流影片之二

2022年5月24日 星期二

在「雄 : youtbue-dl : 下載 ffmpeg 無法下載的串流影片」這篇中,利用 youtube-dl 的選項「--hls-prefer-native」,讓它避免使用 ffmpeg 來下載偽裝為圖片的串流影片,好處是可以一個網址來下載整個影片,不過因為它還是帶有圖片的識別資料,最後仍然要處理這部份,一般的影音播放工具才會識別出它是影片,才能正常播放。

後來試了一下,其實只要將帶有圖片識別資料的影片檔,去掉最前面的 3 bytes (通常是 PNG、BMP、JPG  ... ),就可以利用 ffmpeg 來進行轉存為正常影片了。

假設用 youtube-dl 下載回來的串流影片檔的檔名為 NG.mp4,想要去掉前 3 bytes (也就是由第 4 bytes 讀起),就利用底下的指令來輸出為正常的影片 OK.mp4:

ffmpeg -protocol_whitelist subfile,file -start 4 -i subfile:NG.mp4 -map 0 -c copy OK.mp4

再者,因為 youtube-dl 可以利用「--exec」的選項來指定,在影片下載並儲存完後,接著要針對輸出的檔案執行的命令。讓「--hls-prefer-native」和「--exec」同時使用,前段由 youtube-dl 來下載偽裝為圖片的串流影片,後段交由 ffmpeg 來轉為正常影片。

使用前,要先確認 youtube-dl 和 ffmpeg 都放在一起了,然後執行底下的指令:

youtube-dl ---hls-prefer-native   --exec "ffmpeg -protocol_whitelist subfile,file -start 4 -i subfile:{} -map 0 -c copy {}.mp4" URL

上面的指令中, URL 是要下載的串流影片網址。

如果和前面尚未合併的指令比較一下,有沒有發現到:

  • 輸入的「NG.mp4 」檔名被換為「{}」。
  • 輸出的「OK.mp4」檔名被換為「{}.mp4」。

當使用 youtube-dl 的 --exec」的選項,後面指令的字串裡,「{}」代表最後 youtube-dl 儲存的檔名,這樣滿方便的,我們除了使用 youtube-dl 預設的檔名外,也能使用「-o」的選項來自訂檔名,利用「{}」可以自動幫我們替換掉。

不過,為了讓原始檔跟被 ffmpeg 處理過的檔案同時存在,輸出時,在原始檔名的字尾又加上了「.mp4」({}.mp4),所以如果 youtube-dl 中使用了「-o test.mp4」,ffmpget 處理完就會變成「test.mp4.mp4」。

如果 youtube-dl 下載回來的串流影片是「沒被動過手腳」的正常影片,會是什麼結果呢?

mov,mp4,m4a,3gp,3g2,mj2 @ 0000000000460440] Format mov,mp4,m4a,3gp,3g2,mj2 detected only with low score of 1, misdetection possible!
[mov,mp4,m4a,3gp,3g2,mj2 @ 0000000000460440] moov atom not found subfile:XXX.mp4: Invalid data found when processing input
ERROR: Command returned error code 1

如果已經是正常影片,在輪到 ffmpeg 進行後續處理時,會類似出現上面的錯誤訊息。

不過沒關係,youtube-dl 已經將影片儲存好了。

所以做一個小結論:

  • 如果執行前面的指令,經過 youtube-dl 和 ffmpeg 處理過的影片,影片的檔名會是 XXX.mp4.mp4 (.mp4 出現兩次)。
  • 如果執行前面的指令, ffmpeg 出現了錯誤訊息,影片的檔名會是 XXX.mp4。

相關文章



2022年4月25日 星期一

FFmpeg : 在聲音檔前面加一小段靜音

2022年4月25日 星期一

 如果想要幫 mp3 音檔的前面,加上一段靜音,怎麼處理。用 FFmpeg 是一定可以的。底下這個討論串中,有好幾種方法:

我選擇使用

adelay filter

例如想將 in.mp3 的最前面加上 250微秒的靜音,就用:

ffmpeg -i in.mp3 -af "adelay=250|250" output.mp3

詳細的用法可以參考 FFmpeg 網站的使用手冊:

在 Windows 中,如何將整個目錄中的 mp3 檔案批次加上靜音呢?

在批次檔中,我們可以利用 FOR 來取得指定路徑中的所有檔名。FOR 怎麼用,可以參考這個討論串:

再套上前面 ffmpeg 的語法,就可以完成囉!寫了個批次檔,記錄如下:

@ECHO OFF
REM ffmpeg 的路徑設定
set ffmpegPath=ffmpeg

REM 在前面加幾微秒的靜音
set silenceMilliSeconds=250

if %1test==test goto error

REM 抓第一個參數為 mp3 資料夾
set sourceFolderName=%1

REM 輸出的資料夾名稱
set outputFolderName=%1\new

REM 建新的資料夾以存放處理好的檔案
mkdir %outputFolderName%

setlocal enabledelayedexpansion
for %%f in (%sourceFolderName%\*.mp3) do (
  rem echo %%f 
  rem echo %outputFolderName%\%%~nf%%~xf
  %ffmpegPath% -i %%f -af "adelay=%silenceMilliSeconds%|%silenceMilliSeconds%" %outputFolderName%\%%~nf%%~xf
)
@echo ON
@echo.
@echo check %outputFolderName%
@echo.
goto end 

:error
@echo ON
@echo.
@echo %0 MP3_folder_name
@echo.

:end

假設上面的指令稿儲存到 convert.bat 中,而 mp3 的檔案都放在 source 資料夾中了,只要執行這樣的指令:

convert.bat source

加好靜音片段的新檔案,都會儲存到 source\new 中。

批次檔中的指令,關鍵在如何取出所有 mp3 檔名:

for %%f in (%sourceFolderName%\*.mp3)  do (

幾個重點如下:

  • 「in」後面接的是指定的路徑,取得的檔名會放到 %%f
  • %%~nf 是取出主檔名
  • %%~xf 是取出副檔名

有了這些,其它就是不同字串間的組合了。


2022年3月28日 星期一

youtbue-dl : 下載 ffmpeg 無法下載的串流影片

2022年3月28日 星期一

在前一篇「雄 : FFmpeg : 下載 .m3u8 播放清單的串流影片」中提到有些串流影片的影片片段被包裝成圖片檔,使用 youtube-dl 或 FFmpeg 開啟串流播放清單 .m3u8 檔後,會出現類似底下的錯誤訊息而無法下載影片:


[hls @ 00000000005aff80] Could not find codec parameters for stream 0 (Video: png, none(pc)): unspecif

Consider increasing the value for the 'analyzeduration' and 'probesize' options


仔細想想,造成 youtube-dl 無法下載的原因,應該是被 ffmpeg 給中斷了,因為如果使用 ffmpeg 來下載相同的影片,也會出現一樣的錯誤訊息而中斷。

「怨有頭,債有主。」找到原因了,那就試著看看 youtube-dl 有沒有不使用 ffmpeg 來下載串流檔案的參數。查了一下,還真有!

下面這兩個參數可以控制 youtube-dl 下載串流時使用的工具:

  • --hls-prefer-native
  • --hls-prefer-ffmpeg

從參數的名稱應該不難看出哪一個是使用 ffmpeg,哪一個是不使用 ffmpeg。

如果遇到被包裝成圖片檔的串流影片,而 ffmpeg 又無法被中斷下載,可以試試看,用 youtube-dl 的「 native HLS downloader」,在指令中加入:

--hls-prefer-native

當然囉!下載完,在檔案的最前面還是會有 PNG 的資料,一樣的,用工具去掉最前面的幾個 bytes,影片就能正常播放了。

後記

再搭配 youtube-dl 「--exec」選項,就可以在下載影片完,接著使用 ffmpeg 來將影片轉為正常的格式了。詳情參考於 2022.05.24 的完整做法:

相關文章




2022年3月27日 星期日

FFmpeg : 下載 .m3u8 播放清單的串流影片

2022年3月27日 星期日

 之前下載網路的影片大多是用 youtube-dl,不過,這幾天在某個以前能輕鬆下載的網站中,卻一直吃閉門羹。研究了幾天,稍有一點眉目。

該網站原來是由播放器載入 .m3u8 的串流播放清單,以前播放清單中放的是影片片段的網址,檔名是用 .ts 來當結尾。這次看到的 .m3u8 有兩個特別之處:一個是裡面又放別的 .m3u8 播放清單;另一種則是裡面不是放 .ts 的網址,居然是 .png 或是 .jpg。

.m3u8 檔案中放 .m3u8 這沒什麼,頂多是程序上多卡一道。但是放 .png 或是 .jpg 就妙了!而且如果將網所指的下載回來,開啟後,還真的是圖片,只差呈現的是一片白而已。利用網站的影片播放器可以播放影片,但是利用 youtube-dl 或是 ffmpeg 試著下載影片,就會出現下載到的是圖片,不是影片的警告訊息,當然影片也就下載不了。

好奇心驅使下,利用 HxD Hex Editor 開啟下載回來的 .png :

.png 影片片段檔案的內容

看到檔案的文件內容,有兩處令人覺得有趣:

  • FFmpeg Service01
  • IDAT

查了一下「IDAT」是 PNG 檔案中會用到的,而 FFmpeg 則是我用來處理影片的工具。於是將這個檔案的前 41 bytes (上圖反白的部份)刪除後,另存檔名為 xxx.png.ts。再用 VLC Player 來播播放,哇!看得到影片了吔!

依樣畫葫蘆,將另外四個小片段都刪掉前 41 bytes,並另存為 xxx.ts,仿原來的 .m3u8 製作了一個有新路徑的播放清單,可以用 ffplay 來播放,也可以利用 ffmpeg 將五個小片段合成一個 mp4 影片檔。

另一部影片的 .m3u8 播放清單中則都是 .jpg ,用 HxD Hex Editor 開啟下載回來的 .jpg 檔案:

.jpg 影片片段檔的內容

這個 .jpg 檔案的內容跟前面的 .png 長得滿像的,來比較一下:

.png 影片片段檔的內容

如果將上圖 .png 檔反白的部份刪除,它的檔頭跟 .jpg 就幾乎一樣了。所以我將下載回來的 .jpg 影片片段檔的檔名字尾加上了「.ts」,用 VLC Player 就可以直接播放了。哈!看起來,這支影片片段檔案的格式、編碼沒有問題,只要讓 FFmpeg 能接受叫「.jpg」的檔名就可以,所以要幫它加上底下的參數:


-allowed_extensions ALL 


完整的指令如下:


ffmpeg -allowed_extensions ALL -i https://xx.xx.xx.xx/index.m3u8 -c copy test.mp4


而串流播放清單中使用 .png 的影片處理起來就比較麻煩,我先解決如何用 FFmpeg 來直接下載串流檔案、去掉會誤導為 PNG 圖片的前 41 bytes。假設串流檔案叫 sample.png,使用底下的指令:


ffmpeg -f data  -protocol_whitelist "subfile,file,http,https,tcp,tls" -start 41 -i subfile:https://xx.xx.xx.xx/sample.png -map 0 -c copy -f data  sample.png.ts


輸入旳參數,去掉前 41 bytes 的關鍵:

  • -start 41 -i subfile:

如果出現 protocol whitelist 關鍵字的錯誤訊息,就再加上:

  • -protocol_whitelist "subfile,file,http,https,tcp,tls"

為了保持原來的編碼,輸入和輸出都加上:

  • -f data

輸出的編碼用 copy 的:

  • -c copy

下載並處理串流檔案的指令搞定了,剩下就是利用 PHP 去分析 index.m3u8 ,產生每一個串流檔案的處理指令,並通通放到一個批次檔裡,這樣就可以一口氣將有檔案下載回來。順便也製作一個帶有 .ts 新檔名的播放清單,方便串流檔案下載回來後,再以 FFmpeg 來合併成 .mp4 影片檔。

目前利用上述的方法,以 FFmpeg 來下載被動過手腳的影片是可行,有空再來研究一下,是不是還有更簡便的方式或工具。

相關文章


2018年10月30日 星期二

FFmpeg : 切割聲音檔

2018年10月30日 星期二
如果想將一個聲音檔或是影片檔切割,使用 FFmpeg 就可以輕鬆完成任務。

例如底下的指令:

ffmpeg -i input.mp3 -f segment -segment_time 300 -c copy out%03d.mp3

解析一下各參數:
  • -i 後面接的 input.mp3 是要分割的 mp3 檔案。
  • -f segment 指定以固定時間來切割。
  • -segment_time 後面接的 300 是指定每 300 秒為一個檔案。
  • -c copy 指定以原來的編碼來輸出檔案。
  • out%03d.mp3 是輸出的檔名,會以三位數字,自動編號的檔名。



除了用固定長度來切割,也可以用指定開始時間和結束時間的方式來切割,此部份在之前的另一篇「雄 : FFmpeg : 指定要加特效的時間點」中已寫過,就不再贅述。


相關文章




2017年5月27日 星期六

FFmpeg : 指定要加特效的時間點

2017年5月27日 星期六
2016年底的這一篇「雄 : FFmpeg : 影片剪接與加馬賽克」中利用了 youtube-dl 下載影片,並以 FFmpeg 為剪接、加馬賽克的工具,不過,當時不知道自己的 FFmpeg 版本太舊,以致於Timeline editing 的選項一直沒試成功,最後是用土法鍊鋼的方法完成了想達到的效果。這兩天心血來潮,更新了 FFmpeg ,花了一點時間研究了 Timeline editing 選項,再次體驗了 FFmepg 的強大。

這一篇就來細說重頭,一步驟一步驟的練功,最後建構出在指定位置、指定時段打馬賽克的影片。

2016年12月10日 星期六

FFmpeg : 影片剪接與加馬賽克

2016年12月10日 星期六
影片的剪輯不一定要使用圖形界面來操作的,如果只是想進行簡單的剪接而已,利用 ffmpeg 這個自由軟體,下指令即可進行剪接,甚至加上特效。

以底下的某化妝品廣告影片為例:



分析原廣告片,在 00:02:28.500 和 00:02:46.001 以後各有 1.5 秒 和 2 秒長的時間會出現商品的名稱,另外在 00:03:13 以後會有全版的廣告。片尾的廣告只要截掉不取即可,不過中間會有兩段要為商品名稱加上馬賽克。

本篇中會使用到兩個工具,都可以在網路中找到:

影片下載

在 YouTube 中的影片,可以利用 youtube-dl 下載。假設我們將下載回來的 FullHD 的影片儲存為 source.mp4。

切割影片

利用 ffmpeg 將原始影片(本例中的 source.mp4)切割為五分段,並輸出為 s1.mp4、s1.mp4、s1.mp4、s1.mp4、s1.mp4,五個影片檔。指令如下:

ffmpeg -i source.mp4 -ss 00:00:00.00 -t 00:02:28.500 -y -c copy s1.mp4 
ffmpeg -i source.mp4 -ss 00:02:28.501 -t 00:00:01.500  -y -c copy s2.mp4 
ffmpeg -i source.mp4 -ss 00:02:30.001 -t 00:00:16.000  -y -c copy s3.mp4 
ffmpeg -i source.mp4 -ss 00:02:46.001 -t 00:00:02.00 -y -c copy s4.mp4 
ffmpeg -i source.mp4 -ss 00:02:48.001 -t 00:00:25.00 -y -c copy s5.mp4

上述指令中,「-ss」設定了分段影片的開始時間,而「-t」設定了分段影片的長度。

加馬賽克

我們可以利用 ffmpeg 的濾鏡功能來為 s2.mp4 和 s4.mp4 這兩段有 mark 的地方加上馬賽克。

下載回來的影片,解析度是 1920 x 1080 ,而

  •  s2.mp4 中需要加馬賽克的大小假設為 960x540,放置的座標為 (380,270)
  •  s4.mp4 中需要加馬賽克的大小假設為 1160x540,放置的座標為 (380,270)

最後再用原來的檔名覆蓋儲存即可。執行底下的兩行指令:

ffmpeg -i s2.mp4  -filter_complex  "[0:v]crop=960:540:380:270,boxblur=10[fg];  [0:v][fg]overlay=380:270[v]" -map "[v]" -map 0:a -c:a copy -movflags +faststart  -y s2.mp4 
ffmpeg -i s4.mp4  -filter_complex  "[0:v]crop=1160:540:380:270,boxblur=10[fg];  [0:v][fg]overlay=380:270[v]" -map "[v]" -map 0:a -c:a copy -movflags +faststart  -y s4.mp4
上面的濾鏡參數:

  • [0:v] : 指出是針對第一個影片設定。
  • crop=960:540:380:270 在座標 (380, 27) 處取 960x540 大的畫面
  • boxblur : 馬賽克

連接影片

分段影片都處理好了,最後我們利用 ffmpeg 將 s1.mp4、s2.mp4、s3.mp4、s4.mp4、s5.mp4 五個檔案連接起來,並儲存為 new_movie.mp4,執行底下的這行指令:

ffmpeg -i s.mp4 -i out2.mp4  -i out3.mp4  -i out4.mp4  -i out5.mp4 -filter_complex concat=n=5:v=1:a=1 -y new_movie.mp4

concat 參數的部份:

  • n=5 : 有 5 個影片
  • v=1 : 有影片
  • a=1 : 有聲音


透過前面的操作以後,最後輸出的影片裡,看不到商品的名稱了。ffmpeg 實在好強,有空再來研究一下別的玩法。

後記

學而後知不足,2017年五月底再看這篇文章以後,才了解在整理這篇時有多麼土。其實 FFmpeg 如果用 version 2.0 以後的版本,有更簡單的方法。強烈的建議如果想幫影片加上多個不同的馬賽克,可以參考底下這篇中的方法:



相關文章



2015年2月27日 星期五

用 FFmepg 為影片加字幕

2015年2月27日 星期五
想幫影片加字幕,試過了格式工廠、FreeMake(免費版) 的工具,有圖形界面,不過,被一堆看不懂的影音參數給打敗了,不熟悉的結果是,等很久、轉了好幾次、影片的畫質變得更差......,我不過是要加字幕啦!

看 VLC 有儲存的功能,不過加字幕還是失敗,到現在還是不知道哪個環節錯了。最後還是選擇用 FFmepg ,以一行指令完成任務。

假設:

  • 原始的影片檔名為:source.mp4
  • 字幕檔的中文編碼用「ANSI」,而檔名為:source.srt
  • 加了字幕後的影片要輸出的檔名是:output.mp4

影音都保持原來的內容,只加入字幕軌,執行底下的指令:

ffmpeg.exe -i source.mp4 -sub_charenc CP950 -i source.srt -c:s mov_text -c:v copy -c:a copy   output.mp4

上面 ffmpeg.exe 、source.mp4、source.srt 及 output.mp4 的路徑記得自行修改為存放的路徑。

指令的參數簡單說明一下:

  • -i source.mp4 : 指定影片的來源檔案。
  • -sub_charenc CP950 : 字幕中的文字編碼,以 ANSI 編碼的中文用 CP950 即可。
  • -i source.srt  : 指定字幕檔案。
  • -c:s mov_text : 加入 MP4 或 MOV 的字幕軌。
  • -c:v copy : 影像的內容直接用來源檔中的,不做更動。
  • -c:a copy : 聲音的內容直接用來源檔中的,不做更動。


這種方式由於不用重新轉檔,非常有效率,一下子就好了。FFmpeg 真是一個強大的跨平臺影片處理工具,改天再來好好的研究研究。


2013年4月15日 星期一

FFmpeg : 以 Webcam 來進行縮時攝影

2013年4月15日 星期一
今天和同事分享了以 Raspberry PI + streamer + mencoder 所製作的縮時攝影影片,有人問到如何製作,衍生出在 Windows 要用何種程式的問題。mencoder 由於是 MPlayer 中的一部份,有 Windows 的版本,但是 streamer 似乎只有 Unix like 的版本。找了一下,另外一個可以用來抓 Webcam 影像並重組成縮時影片的 FFmpeg 也有 Windows 的版本,試完了才對這個工具有了一番新的認識,只能說 FFmepg 這個自由軟體實在太強大了,有關影音的處理,不但功能繁多,而且還跨各種作業系統,下面就來看看如何以 FFmpeg 一手包辦由 Webcam 取得影像,並轉成縮時影片的方法。
 
雄::gsyan © 2009. Design by Pocket