ffmpeg -i *.ts -i *.vtt -attach *.jpeg \
-c copy \
-metadata title="insert title here" \
-metadata description="insert description here" \
-metadata date_released=2020 \
-metadata:s:t:0 mimetype=image/jpeg -metadata:s:t:0 filename=cover_land.jpg \
-metadata:s:a:0 language=ger -metadata:s:s:0 language=ger \
output.mkv
-c:v libx265 # re-encode as hevc
- source: https://www.reddit.com/r/ffmpeg/comments/fw4jnh/how_to_make_ffmpeg_keep_attached_images_in_mkv_as/
- cover art specifications: https://www.matroska.org/technical/attachments.html
ffmpeg -i video.mkv -attach cover.jpg -attach small_cover.jpg -map 0 -c copy \
-metadata:s:t mimetype=image/jpg \
-metadata:s:t:0 filename=cover.jpg \
-metadata:s:t:1 filename=small_cover.jpg \
out.mkv
- source: https://trac.ffmpeg.org/wiki/Scaling
- cover art specifications: https://www.matroska.org/technical/attachments.html
ffmpeg -i vert-cover-original.jpg -vf scale=600:-1 cover.jpg
ffmpeg -i vert-cover-original.jpg -vf scale=120:-1 small_cover.jpg
ffmpeg -i land-cover-original.jpg -vf scale=-1:600 cover_land.jpg
ffmpeg -i land-cover-original.jpg -vf scale=-1:120 small_cover_land.jpg
ffmpeg -i movie.mkv -map 0:v -map -0:V -c copy cover.jpg
mapping: include video streams, exclude all normal video streams
ffmpeg -i input-x264.mkv -attach cover.jpg -c copy -c:v libx265 \
-map 0 -map -0:v:m:filename \
-metadata:s:t:0 mimetype=image/jpeg -metadata:s:t:0 filename=cover.jpg \
output-x265.mkv
- doesn't properly copy input's cover images, apparently? hence re-adding manually
- codecs: copy all, use
libx265
for video streams - mapping:
- include all streams from input 0
- exclude the video stream with metadata
filename
(which only the cover art video stream has)
if subtitles are too early
ffmpeg -itsoffset 22 -i f.mkv -c copy subtitles.vtt
if subtitles come too late (there's a gap at the beginning)
ffmpeg -itsoffset -22 -i f.mkv -c copy subtitles.vtt
https://stackoverflow.com/questions/7333232/how-to-concatenate-two-mp4-files-using-ffmpeg
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'
to quickly generate a list of all (matching) files, use this bash script line:
find -type f -name '*.mp4' | sed "s/.*/file \'&\'/" | tee files.txt
ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4
- starting at 0:30, ending 10 seconds later (0:40)
ffmpeg -ss 00:00:30.0 -t 00:00:10.0 -i input.mp4 -c copy output.mp4
# or:
ffmpeg -ss 00:00:30.0 -to 00:00:40.0 -i input.mp4 -c copy output.mp4
“Note that -t is an output option and always needs to be specified after -i.” – https://superuser.com/questions/138331/using-ffmpeg-to-cut-up-video
ffmpeg -ss 30 -t 3 -i input.mp4 -vf "fps=15,scale=640:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" -loop 0 output.gif
- http://ffmpeg.org/pipermail/ffmpeg-user/2018-December/042231.html
- https://wiki.multimedia.cx/index.php/FFmpeg_Metadata
- itunes metadata list in ffmpeg source code http://git.videolan.org/?p=ffmpeg.git;f=libavformat/movenc.c;h=6dab519;hb=HEAD#l3508
ffmpeg -i Angekommen*.mp4 \
-filter:v "crop=in_w:in_h-64:0:32" \
-c:v libx265 \
-attach cover.jpg -attach small_cover.jpg \
-metadata language="deu" \
-metadata description="Juana, a 17-year-old wheelchair user, aims to explore her sexuality but is ashamed of her body. Trying to find her place in a new high school, she will go through failure, friendship, fear and politics until she builds her own pride." \
-metadata:s:v:0 language="deu" \
-metadata:s:a:0 language="spa" \
-metadata:s:t mimetype=image/jpg \
-metadata:s:t:0 filename=cover.jpg \
-metadata:s:t:1 filename=small_cover.jpg \
-metadata show="1 Meter 20" \
-metadata release_date=2021 \
-metadata season_number=1 \
-metadata title="Angekommen" \
-metadata episode_sort=1 \
"1 Meter 20 - S01E01 - Angekommen.mkv"
https://mkvtoolnix.download/doc/mkvpropedit.html
mkvinfo movie.mkv
mkvpropedit movie.mkv --set title="The Movie"
mkvextract movie.mkv attachments 1:cover.jpg
mkvpropedit movie.mkv --add-attachment movie-cover.jpg \
--attachment-name cover.jpg --attachment-mime-type "image/jpeg"
https://superuser.com/questions/609113/how-to-add-and-remove-subtitles-in-an-mkv-file
mkvmerge -o output.mkv --language 0:ger \
input.mkv subs.srt
mkvmerge --list-languages | grep German
let convTime = (h, m, s, ms) => ms + s * 1000 + m * 1000 * 60 + h * 1000 * 60 * 60
let convText = text => convTime(...Array.from(text.split(/:|\./)).map(t => Number(t)))
['00:55:08.54', ..., '00:03:10.44'].forEach(t => console.log(convText))
// => [3341000, ..., 3308054]
// array of chapter lengths
[3341000, ..., 3308054].reduce((pre, cur) => { console.log(pre, pre + cur - 1); return pre + cur }, 0)
let toTime = m => `${Math.floor(m % (1000 * 60 * 60 * 60) / 1000 / 60 / 60)}:${Math.floor(m % (1000 * 60 * 60) / 1000 / 60)}:${Math.floor(m % (1000 * 60) / 1000)}.${m % 1000}`
# get current titles from mkv files and write them to titles.txt
for f in **/*.mkv; do echo $f >> titles.txt; mkvinfo $f | grep Title >> titles.txt; done
# then i used visual studio code to change titles and format the lines to form this command:
mkvpropedit "videofile1.mkv" -s title="video title 1"
find -name 'seg-*-f1-a*' | sort -V | while read f; do cat $f >> audio.ts; done
find -name 'seg-*-f9-v*' | sort -V | while read f; do cat $f >> video.ts; done
ffmpeg -i video.ts -i audio.ts -map 0:v -map 1:a -c copy output.mp4
yes, this has nothing to do with ffmpeg
for f in *.mkv; do echo "${f%.*}"; done
for f in *.mkv; do n="${f%.mkv}"; ffmpeg -i "$f" "$n.eng.srt"; done
or even this, so i can log out of the ssh session while it completes its task
nohup bash -c 'for f in *.mkv; do n="${f%.mkv}"; ffmpeg -i "$f" "$n.eng.srt"; done' &
renames
One Piece Temporada 5 Episodio 381.ass 381 - A New Crewmate! The Musician, Humming Brook!.mkv
to
381 - A New Crewmate! The Musician, Humming Brook!.spa.ass 381 - A New Crewmate! The Musician, Humming Brook!.mkv
for i in {351..381}; do vid=($i*.mkv); sub=(*$i.ass); name="${vid%.*}"; mv "$sub" "$name.spa.ass"; done
for f in *.ass; do ffmpeg -i "$f" "${f%.*}.srt"; done
for f in *.wav; do ffmpeg -i "$f" -b:a 128k "${f%.wav}.opus"; done
for f in VID_*.mp4; do
ffmpeg -i "$f" "$f.mp4"
touch --no-create --reference "$f" "$f.mp4"
done
# double-check, then
for f in VID_*.mp4.mp4; do mv "$f" "${f%.mp4}"; done
https://github.com/elizagamedev/vobsubocr
for f in *.mkv; do mkvextract "$f" tracks 5:"${f%.mkv}.spa.sub"; done
for f in *.spa.idx; do echo $f; vobsubocr --lang spa "$f" -o "${f%.idx}.srt"; done
rm *.spa.idx *.spa.sub
i'm sure there's a more elegant way
for f in *.mkv; do echo $f; mkvinfo "$f" | grep -B7 "Language: spa"; done
sed -i 's/|/I/g' *.srt
for f in VID_20240916_*; do ffmpeg -i $f -vf "scale='if(gt(iw,ih),-2,720)':'if(gt(iw,ih),720,-2)'" -c:a copy ${f%.*}-scaled.mp4; touch -r $f ${f%.*}-scaled.mp4; done
this has nothing to do with ffmpeg
for f in SAM_*.JPG; do mv $f $(date -r $f +IMG_%Y%m%d_%H%M%S.jpg); done
nothing to do with ffmpeg
for f in *.mp3; do mv "$f" "${f/replace/with}"; done