發表文章

目前顯示的是 12月, 2019的文章

用ffmpeg結合影片和聲音檔

ffmpeg.exe -i DJI_0106_rotated.mp4 -i DJI_0106.wav -map 0:0 -map 1:0 -acodec mp3 -vcodec copy success.mp4 輸入mp4影片和wav聲音檔, 因為wave無壓縮會比較大, 所以影片維持原始格式,audio選擇用mp3壓縮 -map 0:0是指第1個輸入的檔案的第1個stream, 通常第一個stream都是影片部分, 如果結合影音失敗, 要確認是第幾個stream, 建議用ffprobe對你的影片檔案做分析,看是哪個stream才是影片部分 -map 1:0是指第2個輸入的檔案的第1個stream, 因為我第二個是wav聲音檔, 只有唯一的聲音資料

用ffmpeg打Multicast影音串流

直接把存下來TS打出去 ffmpeg -re -threads 4 -i part.ts -vcodec copy -acodec copy -f mpegts udp://224.1.2.4:12345 -stream_loop -1 -threads 4 使用4個thread來處理 -vcodec copy, -acodec copy 視訊跟音訊都不處理直接拷貝下來 -f mpegts 輸出格式為mpegts, -stream_loop 1是打2次, 設定-1是無限loop, 0是預設值,表示打1次不loop, 1是多loop一次表示播兩次,以此類推 實際上ffmpeg會parse stream的內容,若是檔案內有使用ffmpeg內未包含的多媒體模組,就打不出去 如果要調整ts的packet size可以用pkt_size=來指定,如果還有別的參數可以用&分隔,不過記得要用雙引號刮起來,不然會被bash認為是要背景執行 ffmpeg -re -threads 4 -i part.ts -vcodec copy -acodec copy -f mpegts "udp://224.1.2.4:12345?pkt_size=1316&fifo_size=50000000" -stream_loop -1

設定Ubuntu使用IGMPv2及解決收不到IGMP封包問題

設定Ubuntu使用IGMPv2 因為Ubuntu要修改force_igmp_version內容需要用sudo提升權限,所以像下面這行指令直接在echo前面打sudo在前面是沒用的,因為檔案輸出還是本身權限 sudo echo 2 > /proc/sys/net/ipv4/conf/${YOUR_NETWORK_DEVICE}/force_igmp_version 使用sudo指令來修改可用下面兩種 方法1. 用tee指令 echo 2 | sudo tee /proc/sys/net/ipv4/conf/${YOUR_NETWORK_DEVICE}/force_igmp_version 方法2. 用sh指令設置 sudo sh -c "echo 2 > /proc/sys/net/ipv4/conf/${YOUR_NETWORK_DEVICE}/force_igmp_version" 方法3. 用sysctl設定 sudo sysctl net.ipv4.conf.${YOUR_NETWORK_DEVICE}.force_igmp_version=2 上面都是針對單一網路裝置, 另外也有對全系統網路裝置的設定 sudo sysctl net.ipv4.conf.all.force_igmp_version=2 上述三種方法都是暫時性的, 如果系統要在開機時套用,請把設定寫在 /etc/sysctl.conf 解決收不到IGMP封包的問題 此外,網路上有些解法是會建議要設定rp_filter為0,讓封包不會被過濾。我個人的經驗是主要還是force_igmp_version有全域跟網卡自己的要先釐清是否有改好,再來看rp_filter。 sudo sysctl net.ipv4.conf.${YOUR_NETWORK_DEVICE}.rp_filter=0 以上設定如果要開機時套用,請把設定寫在 /etc/sysctl.conf

用ffmpeg播放/存檔Multicast

偵測Multicast格式 ffprobe -i udp:// 224.1.2.4:1234 將Multicast存檔 ffmpeg -i udp:// 224.1.2.4:1234  -codec copy saved.ts 如果偵測是ts封包,可以用copy的方式進行存檔 如果偵測式其他封包,可以用對應的格式存檔 播放Multicast ffplay -i udp://224.1.2.4:1234 -x 1280 -y 720 限制播放的大小是1280x720,避免太占用電腦螢幕無法操作界面 ffplay -i udp://224.1.2.4:1234 -sync audio 使用audio master的方式做AV Sync ffplay -i udp://224.1.2.4:1234 -nodisp 不顯示畫面 設定播放的字幕 ffplay -sst 2 -i new.ts -sst 指定第三個subtitle串流, 0為第一個

用ffmpeg解出HDR10影片的yuv檔案

只抓video部份, ffmpeg -i video.mp4 -vcodec copy -an video_only.mp4 用ffprobe偵測格式 ffprobe -i  4k60phdr10.mkv 解出10秒鐘HDR 10bit的yuv原始資料, 建議先用ffprobe看格式 ffmpeg -i 4k60phdr10.mkv -t 10 -pix_fmt yuv420p10le -y output.10bit.yuv 若想只解出處理影片 指定起始時間1秒,長度5秒 ffmpeg -i test.mp4 -ss 1 -t 5 -c:v rawvideo -pix_fmt yuv420p test.yuv 指定處理張數100張 ffmpeg -i test.mp4 -frames 100 -c:v rawvideo -pix_fmt yuv420p test.yuv

用ffmpeg抓出影片部分並旋轉90度

這個方法僅改變影音檔的metadata,所以處理速度快,但是對於一些不支援旋轉屬性的metadata的播放器沒有效果 如果發現設定了90度處理後沒變的話, 是因為影片metadata本來有寫轉90度, 改看看0度或270度再試試 dpn1是指drive,path,name,變數1 x1是指副檔名(extension),變數1

用ffmpeg串接多個影音檔案

官方文件其實有寫怎麼做串接影音檔案 http://ffmpeg.org/ffmpeg-formats.html#concat 1. 產生要串接的檔案列表 (for %%i in (*.wav) do @echo file '%%i') > mylist.txt 2. 執行串接指令 ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.wav 我手動產生串接檔案DJI_0098_list.txt內容,還要寫file空格加上檔案路徑,路徑要注意跳脫字元的問題或是加上單引號''讓字串不處理 file E:\\20191217\\DJI_0098_001.MP4 file E:\\20191217\\DJI_0098_002.MP4 file E:\\20191217\\DJI_0098_003.MP4 執行指令 ffmpeg.exe -f concat -safe 0 -i DJI_0098_list.txt -c copy DJI_0098.MP4 -safe 0是不檢查指定的檔案路徑中是否含有不合法字元 比較懶的方式是寫好串接文字檔後,丟進下面這個script讓他跑,就會用文字檔名當作串接後的MP4檔名 另外官方針對一些視訊, 需要再調整的部分可以參考下面 http://www.ffmpeg.org/faq.html#How-can-I-concatenate-video-files_003f 下面這個寫法在我的案例(H.264 4k MP4)是無法成功的,影片長度跟第一個檔案的一樣。 ffmpeg -i "concat:input1.avi|input2.avi|input3.avi" -c copy output.avi