Puzzled with file descriptor in Bash (ffmpeg video capture) - linux

I am trying to use file descriptors in Bash and found a problem I cannot solve.
I have to read a video stream coming from the standard output of a command executed in a coproc. This piece of code works as expected :
ffmpeg \
-i <(exec cat <&${COPROC[0]}) \
-c:v $ENCODE_VIDEO_FORMAT_LOSSLESS $ENCODE_VIDEO_OPTIONS_LOSSLESS \
-c:a copy \
-progress /dev/fd/1 \
"${capfile}"
But the cat process is not really useful since ffmpeg -i pipe:<file descriptor> seems to do the same. So I tried the following code which fails with pipe:63: Bad file descriptor
error.
ffmpeg \
-i pipe:"${COPROC[0]}" \
-c:v $ENCODE_VIDEO_FORMAT_LOSSLESS $ENCODE_VIDEO_OPTIONS_LOSSLESS \
-c:a copy \
-progress /dev/fd/1 \
"${capfile}"
The actual script is something a bit complicated but here is a minimal testing code for this issue :
#!/bin/bash
#
ENCODE_VIDEO_FORMAT_LOSSLESS=ffv1
ENCODE_VIDEO_OPTIONS_LOSSLESS="-level 3 -threads 7 -coder 1 -context 1 -g 1 -slices 30 -slicecrc 1"
capfile=capure.mkv
coproc ffmpeg -i file:'Camomille.mkv' -c:v copy -c:a copy -f matroska pipe:1
capture_fd=${COPROC[0]}
echo "hk_capture_pid=${COPROC_PID}"
ffmpeg \
-i pipe:${COPROC[0]} \
-c:v $ENCODE_VIDEO_FORMAT_LOSSLESS $ENCODE_VIDEO_OPTIONS_LOSSLESS \
-c:a copy \
-progress /dev/fd/1 \
"${capfile}"
This is the output of the second ffmpeg command :
ffmpeg version 4.1.4-1build2 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 9 (Ubuntu 9.2.1-4ubuntu1)
configuration: --prefix=/usr --extra-version=1build2 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 22.100 / 56. 22.100
libavcodec 58. 35.100 / 58. 35.100
libavformat 58. 20.100 / 58. 20.100
libavdevice 58. 5.100 / 58. 5.100
libavfilter 7. 40.101 / 7. 40.101
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 3.100 / 5. 3.100
libswresample 3. 3.100 / 3. 3.100
libpostproc 55. 3.100 / 55. 3.100
pipe:63: Bad file descriptor
av_interleaved_write_frame(): Broken pipe
Error writing trailer of pipe:1: Broken pipe
frame= 4 fps=0.0 q=-1.0 Lsize= 48kB time=00:00:00.03 bitrate=10051.1kbits/s speed=3.44x
video:86kB audio:1kB subtitle:0kB other streams:0kB global headers:2kB muxing overhead: unknown
Conversion failed!
This one fails and if you replace -i pipe:${COPROC[0]} by -i <(exec cat <&${COPROC[0]}) a capture.mkv file is created.
I run ubuntu eoan and bash version is : GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu). I upgraded several times since I started with this issue, so it wouldn't be related too much to bash and ffmpeg versions.
If someone can point me to what I do wrong with bash file descriptors I would be grateful.

The file descriptor ${COPROC[0]} is valid only for the shell, not for ffmpeg.
So what you need is :
ffmpeg \
-i pipe:0 \
-c:v $ENCODE_VIDEO_FORMAT_LOSSLESS $ENCODE_VIDEO_OPTIONS_LOSSLESS \
-c:a copy \
-progress /dev/fd/1 \
"${capfile}" <&${COPROC[0]}

Related

Delete lines prior to a specific date in a log file

I have a ffmpeg process log file in which log data get appended to it daily. I want to do a automatic maintainence of this log by going through the log and deleting lines belonging to a certain date.
I tried something but it didn't help.
How should i do it? Please help. Thanks.
Example. To delete all lines prior to Jun 01.
#!/bin/bash
var=`date -d "now-30 day" | awk '{print $3}'`
path="/home/pi/scripts/"
## Removing Entries before 30 Days ####
for logs in $path/process.log; do
awk -v rot=$var '{ if ($NF > rot ) {print $0}}' $logs > $path/temp.log
mv $path/temp.log $logs
done
Example of process.log file which contains data prior to june i want to delete all the previous data.
Oct 28 06:48:15 #####################################Start Time########################################
Stopping Transaction Video Recording
ffmpeg version 4.2.1-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libfribidi --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libxml2 --enable-libxvid --enable-libzimg
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
/dev/v4l/by-id/usb-WN-720P-HD_WN-720P-HD_WN-720P-HD-video-index0: Device or resource busy
Oct 28 06:48:17 #####################################End Time########################################
Oct 29 07:38:13 #####################################Start Time########################################
Stopping Transaction Video Recording
ffmpeg version 4.2.1-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libfribidi --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libxml2 --enable-libxvid --enable-libzimg
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
/dev/v4l/by-id/usb-WN-720P-HD_WN-720P-HD_WN-720P-HD-video-index0: Device or resource busy
Oct 29 07:38:13 #####################################End Time########################################"
This is the data i want to preserve which is of current month's data:
Jun 02 09:49:08 #####################################Start Time########################################
Stopping Transaction Video Recording
ffmpeg version 4.2.1-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 6.3.0 (Debian 6.3.0-18+deb9u1) 20170516
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libfribidi --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libxml2 --enable-libxvid --enable-libzimg
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
[video4linux2,v4l2 # 0x36e75e0] The driver changed the time per frame from 1/5 to 1/30
[mjpeg # 0x36e8530] EOI missing, emulating
Input #0, video4linux2,v4l2, from '/dev/v4l/by-id/usb-WN-720P-HD_WN-720P-HD_WN-720P-HD-video-index0':
Duration: N/A, start: 13731.683520, bitrate: N/A
Stream #0:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (mjpeg (native) -> mpeg4 (native))
Press [q] to stop, [?] for help
I'd use sed.
sed -i.bak '/^Jun 01/,/^Jun 01.*$\n/!d' log.txt
This will create a backup of log.txt named log.txt.bak. But still, I'd suggest you to make a backup first with a different name.
This assumes that Jun 01 exists in the log.txt.
EDITED
#!/bin/bash
target_file='log.txt'
target_date='Jun 01'
line=$(awk -v date="$target_date" '
date==$1" "$2 {
if(n++==0) { line=FNR
} else { n=0 }
} END {
print line-1
}' "$target_file")
if [[ "$line" > 1 ]]; then
sed -i.bak "1,${line}d" "$target_file"
fi
Similar as the above command, It will create a backup file named e.g. log.txt.bak. Change the target_file and target_date according to your needs.
This script will delete all lines prior date even though there are multiple duplicates.
We miss elements for coding waterproof. We need to know a.o. if it possible to find entries from past years in the log files, because the log files don't mention the year of the entries, only the month and the day.
We suppose that a date apparently in the future corresponds to entries of former years. If you run the script in the beginning of January, you will delete entries of December which are younger than 30 days.
This implies the problem can't be solved in a completely satisfactory way without more knowledge. Sometimes the name of the logfiles can contain some useful information about the year that we ignore here.
Anyway, the solution below may work, but it is not very optimal:
#!/bin/bash
#time stamp older entries to keep
ts_now=$(date +"%s" -d now)
ts_oldest_to_keep=$(date +"%s" -d "now - 30 days")
#adapt path to point to the directory where log files are living
path="."
for ts in $(grep "Start Time" "$path/"*".log" | awk '{print $1, $2}' | date +"%s" -f - | sort -u)
do
# get the timestamp corresponding to all the entries to be removed
if [ $ts -lt $ts_oldest_to_keep ] || [ $ts -gt $ts_now ]
then
# convert the timestamp into the string "%b %d" i.e. the abbreviated month
# name in English followed by space and zero padded day of month.
# LC_ALL=C to make sure you get an English name of month
ym=$(LC_ALL=C date +"%b %d" -d "#$ts")
# delete the block of lines beginning with "$ym" and ending with
# the same string
sed -i "/^$ym.*Start Time/,/^$ym.*End Time/d" "$path/"*".log"
fi
done
You first grab all the possible dates from the log files. You convert the date into a time stamp for making a numerical comparison of dates possible, and you use sed to delete block of lines without the need of a temporary file.
Looking for a solution in AWK in one pass shoud also be possible, but AWK misses a standard function to convert easily dates as Jun 01.
Anyway, backup your log files before messing around.

need help using ffmpeg to "concat" multiple audio files (webm, mp4) to make one longer MP3 of audio

I have done some searching (for several hours) and tried to manipulate many examples to work for me, but I still keep coming up empty here.
I am using linux-mint 19, with ffmpeg installed. I have a folder with several audio files. The majority of these are "webm" (with no video) and there are a few "m4a". I am trying to make one long mp3 file from the audio in all of these strung together from start to finish.
Lets say for sake of argument, my directory has the following files:
audio file a.webm
audio file b.webm
audio file c.m4a
audio file d.webm
I found a script that I could write online where someone is creating a file called "mylist.txt" with this bit of code:
# with a bash for loop
for f in ./*.*; do echo "file '$f'" >> mylist.txt; done
# or with printf
printf "file '%s'\n" ./*.* > mylist.txt
this generated a text file with the following type of content:
file './audio file a.webm'
file './audio file b.webm'
file './audio file c.m4a'
file './audio file d.webm'
first, I believe the "./" is causing a problem, because when I look at other examples I don't see this but I am not sure why it is generating this way in my script because I don't see this in web examples online. Second, I have tried to "concate" this with ffmpeg but I'm not sure which is the best option. I found some documentation here:
https://trac.ffmpeg.org/wiki/Concatenate
however this example applies to video specifically
Can anyone lead me in the right direction?
EDIT******
I tried the solution below, with "mylist.txt" as the input and I am getting an error:
user#machine/TEMP$ ffmpeg -i mylist.txt -filter_complex "[0:a][1:a][2:a][3:a]concat=n=20:a=1:v=0[a]" -map "[a]" output.mp3
ffmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 9 (Ubuntu 9.3.0-10ubuntu2)
configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, tty, from 'mylist.txt':
Duration: 00:00:00.40, bitrate: 47 kb/s
Stream #0:0: Video: ansi, pal8, 640x400, 25 fps, 25 tbr, 25 tbn, 25 tbc
Stream specifier ':a' in filtergraph description [0:a][1:a][2:a][3:a]concat=n=20:a=1:v=0[a] matches no streams.
The concat demuxer works best with inputs that all have the same attributes. The concat demuxer documentation states, "All files must have the same streams (same codecs, same time base, etc.)" The concat demuxer is good for when you are trying to avoid re-encoding, but that is not possible with inputs of various formats.
You are providing inputs with arbitrary attributes. Use concat filter instead:
ffmpeg -i a.webm -i b.webm -i c.m4a -i d.webm -filter_complex "[0:a][1:a][2:a][3:a]concat=n=4:a=1:v=0[a]" -map "[a]" output.mp3
Note from the concat filter documentation: "The filtering system will automatically select a common sample format, sample rate, and channel layout for audio streams."
If you want to manually select the sample rate and channel layout, so you know exactly what you will get, add the aformat filter:
ffmpeg -i a.webm -i b.webm -i c.m4a -i d.webm -filter_complex "[0:a]aformat=r=44100:cl=stereo[a0];[1:a]aformat=r=44100:cl=stereo[a1];[2:a]aformat=r=44100:cl=stereo[a2];[3:a]aformat=r=44100:cl=stereo[a3];[a0][a1][a2][a3]concat=n=4:a=1:v=0[a]" -map "[a]" output.mp3

FFmpeg ignoring output pixel format

I am using ffmpeg 4.2.2 on an Ubuntu 20.04 machine to clone the video stream of a USB webcam so that multiple applications can use the same feed. To achieve this, I simply clone to a v4l2 loop back device:
ffmpeg -f v4l2 -i /dev/video0 -codec copy -f v4l2 /dev/video1
So far, this works reasonably well. I am able to successfully access /dev/video1 which presents the same feed as /dev/video0.
Note: To make this work you need to ensure that the v4l2loopback device kernel module is enabled:
modprobe v4l2loopback devices=1
Next I'd like to convert the pixel format of the dummy device as the application that is accessing the dummy device can only handle yuv422p or RGB whereas my source device /dev/video0 provides yuv420p. I thought that this would be a simple task that can easily be handled by presenting ffmpeg with an additional -pix_fmt argument on the output device like so:
ffmpeg -f v4l2 -i /dev/video0 -codec copy -f v4l2 -pix_fmt yuv422p /dev/video1
While ffmpeg starts cloning the stream without any warnings or errors, it is still outputting in yuv420p instead:
joel#joel-ubuntu:~$ ffmpeg -f v4l2 -i /dev/video0 -codec copy -f v4l2 -pix_fmt yuv422p /dev/video1
ffmpeg version 4.2.2-1ubuntu1 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 9 (Ubuntu 9.3.0-3ubuntu1)
configuration: --prefix=/usr --extra-version=1ubuntu1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
[video4linux2,v4l2 # 0x55ca407b9700] Time per frame unknown
Input #0, video4linux2,v4l2, from '/dev/video0':
Duration: N/A, start: 6726.737520, bitrate: N/A
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 640x480, 29.25 tbr, 1000k tbn, 1000k tbc
Output #0, video4linux2,v4l2, to '/dev/video1':
Metadata:
encoder : Lavf58.29.100
Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 640x480, q=2-31, 29.25 tbr, 1000k tbn, 1000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
frame= 76 fps= 34 q=-1.0 Lsize=N/A time=00:00:02.52 bitrate=N/A speed=1.14x
No matter what -pix_fmt I pass, I always end up with yuv420p on the output.
I did several tests with both proper USB UVC webcams as well as DroidCam. The output pixel format never changes as expected. This is also not specific to requesting yuv422p as a pixel format. Also other formats are being ignored. Why is this happening? What am I missing?
Note: I have verified that ffmpeg is capable of the yuv422p pixel format (it is being listed when executing ffmpeg -pix_fmts).
You can't change pixel formats when using -c:v copy. Change to -c:v rawvideo.

Using FFMPEG to split a 16 channel audio input source into 4 seperate 4 channel audio feeds for streaming

I hope someone can help
I am currently trying to split a 16ch Dante audio feed from a separate machine into 4 different audio streams that I can use to then TX via RTMP to Wowza for MPEG-DASH encoding, at present i am just trying to split them into files, I will add the RTMP streaming later.
The biggest issue I am encountering at current is that FFMPEG is returning me this error from my input string
Filter channelsplit:WR has an unconnected output
here is my current input string
ffmpeg -f dshow -i audio="Dante Via Receive (Dante Via)" -filter_complex "[0:a]channelsplit=channel_layout=hexadecagonal[FL][FR][FC][BL][BR][BC][SL][SR][TFL][TFC][TFR][TBL][TBC][TBR][WL][WR]" -map "[FL][FR][FC][BL]" 1-4.wav -map "[BR][BC][SL][SR]" 5-8.wav -map "[TFL][TFC][TFR][TBL]" 9-12.wav -map "[TBC][TBR][WL][WR]" 13-16.wav
and here is the full FFMPEG output
ffmpeg version git-2019-12-26-b0d0d7e Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 9.2.1 (GCC) 20191125
configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
libavutil 56. 37.100 / 56. 37.100
libavcodec 58. 65.100 / 58. 65.100
libavformat 58. 35.101 / 58. 35.101
libavdevice 58. 9.101 / 58. 9.101
libavfilter 7. 69.101 / 7. 69.101
libswscale 5. 6.100 / 5. 6.100
libswresample 3. 6.100 / 3. 6.100
libpostproc 55. 6.100 / 55. 6.100
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, dshow, from 'audio=Dante Via Receive (Dante Via)':
Duration: N/A, start: 103082.790000, bitrate: 1411 kb/s
Stream #0:0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s
File '1-4.wav' already exists. Overwrite? [y/N] y
File '5-8.wav' already exists. Overwrite? [y/N] y
File '9-12.wav' already exists. Overwrite? [y/N] y
File '13-16.wav' already exists. Overwrite? [y/N] y
Filter channelsplit:WR has an unconnected output
I'm also getting the issue where FFMPEG is guessing that the channel count is stereo, which is incorrect but i'm having problems figuring out how to define the input stream as 16ch's of audio
Any help with this would be greatly recieved
Cheers
M
ffmpeg -f dshow -channels 16 -i audio="Dante Via Receive (Dante Via)" -filter_complex "[0:a]channelmap=0|1|2|3[1-4];[0:a]channelmap=4|5|6|7[5-8];[0:a]channelmap=8|9|10|11[9-12];[0:a]channelmap=12|13|14|15[13-16]" -map "[1-4]" 1-4.wav -map "[5-8]" 5-8.wav -map "[9-12]" 9-12.wav -map "[13-16]" 13-16.wav
Try adding the -channels 16 dshow input option.
Filter output labels can't be combined in -map, so do all mixing with filters and give each -map a single label.
channelsplit only outputs channels as individual streams, and it does not mix multiple channels into a single stream, so channelmap is used instead.
I don't have dshow so I couldn't test this.

ffmpeg replace part of audio file with looped audio

I am quite new to ffmpeg and I am trying to replace a part of a first audio file with another second file. The second file can be too short, so some sort of loop should exist.
After some research I came up with the following command arguments and it gives me the output as long as I only do one replacement. But I would like to do multiple replacements. So any help on what I am doing wrong? Any suggestions/remarks on the way of working are also very welcome.
(Any typos in the commands below can be ignored, I generate the command by script and for ease of use I simplified the names.)
Works (One replacement):
"ffmpeg.exe" -y -i "first.wav" -i "second.wav" -filter_complex "[1:a][1:a][1:a]concat=n=3:v=0:a=1,asetpts=PTS-STARTPTS[replaceBase];[0:a]atrim=0:3,asetpts=PTS-STARTPTS[partA];[replaceBase]atrim=0:2,asetpts=PTS-STARTPTS[replaceA];[0:a]atrim=start=5,asetpts=PTS-STARTPTS[partB];[partA][replaceA][partB]concat=n=3:v=0:a=1[aout]" -map "[aout]" Out.wav
Works Not (Multiple replacements):
"ffmpeg.exe" -y -i "first.wav" -i "second.wav" -filter_complex "[1:a][1:a][1:a]concat=n=3:v=0:a=1,asetpts=PTS-STARTPTS[replaceBase];[0:a]atrim=0:3,asetpts=PTS-STARTPTS[partA];[replaceBase]atrim=0:2,asetpts=PTS-STARTPTS[replaceA];[0:a]atrim=5:4,asetpts=PTS-STARTPTS[partB];[replaceBase]atrim=0:2,asetpts=PTS-STARTPTS[replaceB];[0:a]atrim=start=6,asetpts=PTS-STARTPTS[partC];[partA][replaceA][partB][replaceB][PartC]concat=n=4:v=0:a=1[aout]" -map "[aout]" Out.wav
ffmpeg version N-76860-g72eaf72 Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 5.2.0 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-decklink --enable-zlib
libavutil 55. 9.100 / 55. 9.100
libavcodec 57. 16.100 / 57. 16.100
libavformat 57. 19.100 / 57. 19.100
libavdevice 57. 0.100 / 57. 0.100
libavfilter 6. 15.100 / 6. 15.100
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
libpostproc 54. 0.100 / 54. 0.100
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, wav, from '3897583stereo.wav':
Duration: 00:00:12.07, bitrate: 256 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 8000 Hz, 2 channels, s16, 256 kb/s
Guessed Channel Layout for Input Stream #1.0 : stereo
Input #1, wav, from 'beep-021.wav':
Metadata:
encoder : Lavf57.19.100
Duration: 00:00:00.30, bitrate: 1413 kb/s
Stream #1:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 2 channels, s16, 1411 kb/s
[wav # 057242c0] Invalid stream specifier: replaceBase.
Last message repeated 1 times
Stream specifier 'STREAM CUT matches no streams.
Thanks in advance!
I managed to find a workaround (or maybe just how it should be done) by splitting the looped stream with asplit. Remarks for the way of processing are still welcome...
"ffmpeg.exe" -y -i "first.wav" -i "second.wav" -filter_complex "[1:a][1:a][1:a]concat=n=3:v=0:a=1,asetpts=PTS-STARTPTS[replaceBase];[replaceBase]asplit=2 [replaceA][replaceB];[0:a]atrim=0:3,asetpts=PTS-STARTPTS[partA];[replaceA]atrim=0:2,asetpts=PTS-STARTPTS[replaceTrimmedA];[0:a]atrim=5:6,asetpts=PTS-STARTPTS[partB];[replaceB]atrim=0:2,asetpts=PTS-STARTPTS[replaceTrimmedB];[0:a]atrim=start=8,asetpts=PTS-STARTPTS[partC];[partA][replaceTrimmedA][partB][replaceTrimmedB][PartC]concat=n=4:v=0:a=1[aout]" -map "[aout]" Out.wav
Regards,

Resources