FFmpeg create output directory hierarchy
Nope, FFmpeg can't do that 🤬
We can add a few lines to the top of your record.sh
script to create the directory for you, though.
#!/bin/sh
BASEDIRECTORY = /raid1/homes/share/public/recordings/queue/bedroom
YEAR=$(date +"%Y");
MONTH=$(date +"%m");
DAY=$(date +"%d");
# Create a directory tree for the day
# using the current year, month, and day
mkdir -p $BASEDIRECTORY/$YEAR/$MONTH/$DAY
# Start FFmpeg hourly recordings
ffmpeg -stimeout 600\
-rtsp_transport udp \
-i rtsp://192.168.1.240/unicast \
-c copy \
-map 0:0 \
-f segment \
-segment_time 3600 \
-segment_wrap 100 \
-segment_format mov \
-strftime 1 \
-reset_timestamps 1 \
"$BASEDIRECTORY/$YEAR/$MONTH/$DAY/%H-%M.mp4"
Now we just need record.sh
to restart overnight to create a new folder for the $DAY
. That sounds like a perfect job for cron: How to write a cron that will run a script every day at midnight?
Note: this script now requires root privilege so if you're getting the error below and cron
isn't working, make sure you're typing sudo ./record.sh
while testing and install your crontab as the root user like this: sudo crotab -u root -e
, as @dashesy points out in his comment.
This is because mkdir
with the -p
or --parent
option requires root privilege and if the directory isn't there FFmpeg will throw this error:
Failed to open segment '/raid1/homes/share/public/recordings/queue/bedroom/2019/01/31/10-37.mp4'
Could not write header for output file #0 (incorrect codec parameters ?): No such file or directory
Related videos on Youtube
David
Updated on June 24, 2022Comments
-
David about 2 years
Recently bought an ip-cam which outputs a RTSP stream. I'm using the segment option of FFmpeg to create 60 minute long recordings.
I want FFmpeg to write the files to a directory based on
Year/Month/Date
, and write to a fileHour-Minute.mp4
For example:/raid1/homes/share/public/recordings/queue/bedroom/2017/04/23/13-05.mp4
for a recording started on 23 april 2017, 13:05.Unfortunately FFmpeg seems to not create the directory hierarchy. FFmpeg quits since the directory can not be found.
Input #0, rtsp, from 'rtsp://192.168.1.240/unicast': Metadata: title : LIVE555 Streaming Media v2014.07.04 comment : LIVE555 Streaming Media v2014.07.04 Duration: N/A, start: 0.000750, bitrate: N/A Stream #0:0: Video: h264 (High), yuv420p, 1920x1080, 90k tbr, 90k tbn, 180k tbc Stream #0:1: Audio: pcm_alaw, 8000 Hz, 1 channels, s16, 64 kb/s [segment @ 0x2557300] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead. [segment @ 0x2557300] Failed to open segment '/raid1/homes/share/public/recordings/queue/bedroom/2017/04/23/14-19.mp4' Output #0, segment, to '/raid1/homes/share/public/recordings/queue/bedroom/%Y/%m/%d/%H-%M.mp4': Metadata: title : LIVE555 Streaming Media v2014.07.04 comment : LIVE555 Streaming Media v2014.07.04 encoder : Lavf57.41.100 Stream #0:0: Video: h264, yuv420p, 1920x1080, q=2-31, 90k tbr, 90k tbn, 90k tbc Stream mapping: Stream #0:0 -> #0:0 (copy) Could not write header for output file #0 (incorrect codec parameters ?): No such file or directory
record.sh is as follows:
#!/bin/sh ffmpeg -stimeout 600\ -rtsp_transport udp \ -i rtsp://192.168.1.240/unicast \ -c copy \ -map 0:0 \ -f segment \ -segment_time 3600 \ -segment_wrap 100 \ -segment_format mov \ -strftime 1 \ -reset_timestamps 1 \ "/raid1/homes/share/public/recordings/queue/bedroom/%Y/%m/%d/%H-%M.mp4"
I've tried not using a directory hierachy:
"/raid1/homes/share/public/recordings/queue/bedroom/%Y-%m-%d_%H-%M.mp4"
. This works fine.$ ffmpeg -version ffmpeg version N-80901-gfebc862 Copyright (c) 2000-2016 the FFmpeg developers built with gcc 4.8 (Ubuntu 4.8.4-2ubuntu1~14.04.3) configuration: --extra-libs=-ldl --prefix=/opt/ffmpeg --mandir=/usr/share/man --enable-avresample --disable-debug --enable-nonfree --enable-gpl --enable-version3 --enable-libopencore-amrnb --enable-libopencore-amrwb --disable-decoder=amrnb --disable-decoder=amrwb --enable-libpulse --enable-libfreetype --enable-gnutls --enable-libx264 --enable-libx265 --enable-libfdk-aac --enable-libvorbis --enable-libmp3lame --enable-libopus --enable-libvpx --enable-libspeex --enable-libass --enable-avisynth --enable-libsoxr --enable-libxvid --enable-libvidstab libavutil 55. 28.100 / 55. 28.100 libavcodec 57. 48.101 / 57. 48.101 libavformat 57. 41.100 / 57. 41.100 libavdevice 57. 0.102 / 57. 0.102 libavfilter 6. 47.100 / 6. 47.100 libavresample 3. 0. 0 / 3. 0. 0 libswscale 4. 1.100 / 4. 1.100 libswresample 2. 1.100 / 2. 1.100 libpostproc 54. 0.100 / 54. 0.100
Can FFmpeg create output directories on the go?
-
Stephen almost 5 yearsUpdate: for HLS use
-strftime 1
with-strftime_mkdir 1
and-hls_segment_filename '%Y/%m/%d/%H-%M.ts'
. FFmpeg will create the directory structure. See the FFmpeg documentation here: ffmpeg.org/ffmpeg-formats.html#Options-5 -
john ktejik over 4 yearsHLS? Whats that? Can it do it or not?
-
Travis Britz over 4 yearsNone of this actually requires root, these errors are just because the script was run as root (either in the root user's crontab or run with sudo), so it created directories while running under the root user (therefore owned by root). As long as the script is added to a normal user's crontab and the directories are owned by that user, you can run this script as that user (without root/sudo).