Linux video: Difference between revisions
(35 intermediate revisions by the same user not shown) | |||
Line 4: | Line 4: | ||
* See [[Linux video]] for video support on Linux |
* See [[Linux video]] for video support on Linux |
||
* See [[Linux photo]] for photo support on Linux |
* See [[Linux photo]] for photo support on Linux |
||
* See [[Dv]] for capture and conversion of DV tapes. |
|||
== Play videos == |
== Play videos == |
||
=== Mplayer === |
=== Mplayer === |
||
<source lang="bash"> |
|||
mplayer -ss 30 movie.mp4 # Start playing from 30s |
|||
mplayer -ss 01:00 movie.mp4 # Start playing from 01:00 (1 minute) |
|||
</source> |
|||
;External links |
|||
* http://www.linuxtutorialblog.com/post/tutorial-playing-around-with-mplayer |
* http://www.linuxtutorialblog.com/post/tutorial-playing-around-with-mplayer |
||
;Playing video files |
|||
'''MPlayer''' plays video files. Many video formats are supported. To play a file: |
'''MPlayer''' plays video files. Many video formats are supported. To play a file: |
||
Line 36: | Line 41: | ||
;Playing DVD's |
|||
Here some handy examples. '''Mplayer''' can also be used to play dvd files directly from the harddisk. Check <code>man mplayer</code> for more examples. |
Here some handy examples. '''Mplayer''' can also be used to play dvd files directly from the harddisk. Check <code>man mplayer</code> for more examples. |
||
Line 47: | Line 52: | ||
</source> |
</source> |
||
{{red|bug}}: There is apparently a bug that prevents subtitles to be displayed even though the option <tt>-slang</tt> is given on the command-line. As a workaround press the key {{kbkey|J}} while playback to cycle through the subtitles. |
{{red|bug}}: There is apparently a bug that prevents subtitles to be displayed even though the option <tt>-slang</tt> is given on the command-line. As a workaround press the key {{kbkey|J}} while playback to cycle through the subtitles. |
||
;Configuring |
|||
Edit {{file|~/.mplayer/input.conf}} [https://github.com/philipl/mplayer/blob/master/etc/input.conf] (! It's '''PGDWN''' !): |
|||
RIGHT seek +10 |
|||
LEFT seek -10 |
|||
DOWN seek -60 |
|||
UP seek +60 |
|||
PGUP seek 600 |
|||
PGDWN seek -600 |
|||
=== mpv === |
|||
An improved mplayer2. |
|||
== Record video == |
== Record video == |
||
=== Open Broadcaster Software === |
|||
One of the best free software to record and stream your presentation, live games, etc. A bit difficult to setup, but powerful and excellent results. Linux, Windows, Mac. |
|||
* https://obsproject.com/ |
|||
* https://obsproject.com/wiki/ |
|||
* [https://www.youtube.com/watch?v=9AKhr8wrXvY A nice tutorial] |
|||
<source lang=bash> |
|||
# On Debian |
|||
sudo apt install ffmpeg obs-studio |
|||
</source> |
|||
=== SimpleScreenRecorder === |
=== SimpleScreenRecorder === |
||
'''[http://www.maartenbaert.be/simplescreenrecorder/ SimpleScreenRecorder]''' is a very simple and powerful tool to record desktop on Linux. |
'''[http://www.maartenbaert.be/simplescreenrecorder/ SimpleScreenRecorder]''' is a very simple and powerful tool to record desktop on Linux. |
||
Line 72: | Line 101: | ||
== Encode video == |
== Encode video == |
||
=== HandBrake === |
=== HandBrake === |
||
See [[HandBrake]]. |
|||
'''[https://handbrake.fr/ HandBrake]''' is a powerful, yet easy to use video encoder for Linux. |
|||
=== ffmpeg === |
|||
;Tips - Encode a DVD title |
|||
;TROUBLESHOOT - Make sure stdin is dev/null |
|||
* Click '''Source'''. |
|||
ffmpeg behaves strangely when stdin is fed with data (e.g. when ffmpeg is run within a while loop reading a file) |
|||
* Select DVD to encode, and select folder '''{{file|VIDEO_TS}}''' (don't open it), and click '''OK'''. |
|||
<source lang=bash> |
|||
# AVOID ffmpeg interactive mode or consuming stdin |
|||
ffmpeg ... < /dev/null |
|||
</source> |
|||
;Use yuvj420p to get full 8-bit color range |
|||
By default, ffmpeg would use a compressed color range [16,255]. Use pixel format <code>yuvj420p</code> to get the full color range [https://www.facebook.com/permalink.php?story_fbid=2413101932257643&id=100006735798590]: |
|||
<source lang=bash> |
|||
ffmpeg -i source.mp4 -c:v libx265 -pix_fmt yuvj420p dest.mp4 |
|||
</source> |
|||
;Rescale video: |
|||
<source lang=bash> |
|||
# Use :-1 to keep aspect ratio - might complain if height is odd |
|||
ffmpeg -i input.avi -filter:v scale=720:-1 -c:a copy output.mkv |
|||
</source> |
|||
;Change container: |
|||
<source lang=bash> |
|||
ffmpeg -i input.mkv -c:v copy -c:a copy output.mp4 |
|||
</source> |
|||
;Mux video and audio |
|||
Say {{file|video.mp4}} is a h264 flux, and {{file|audio.wav}} is a wave file: |
|||
<source lang="bash"> |
|||
ffmpeg -i video.mp4 -i audio.wav -vcodec copy -acodec mp3 combined.mp4 |
|||
</source> |
|||
;Concatenate video (with different codecs) |
|||
<source lang="bash"> |
|||
# https://trac.ffmpeg.org/wiki/Concatenate#differentcodec |
|||
# Concatenate |
|||
ffmpeg -i file1.mkv -i file2.flv -i file3.mp4 \ |
|||
-filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa]" \ |
|||
-map "[outv]" -map "[outa]" output.mp4 |
|||
# Concatenate, but use AAC for output audio |
|||
ffmpeg -i file1.mkv -i file2.flv -i file3.mp4 \ |
|||
-filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa]" \ |
|||
-c:a aac \ |
|||
-map "[outv]" -map "[outa]" output.mp4 |
|||
</source> |
|||
;Crop video |
|||
<source lang="bash"> |
|||
# Keep leftmost 480x1080 of video |
|||
ffmpeg -i input_video.mp4 -filter:v "crop=480:1080:0:0" -c:a copy output_video.mp4 |
|||
</source> |
|||
; Custom filtering |
|||
This is from [https://nullprogram.com/blog/2017/07/02/ Rolling Shutter Simulation in C]: |
|||
<source lang=bash> |
|||
ffmpeg -i input.mp4 -f image2pipe -vcodec ppm pipe:1 | \ |
|||
x264 -o output.mp4 /dev/stdin |
|||
</source> |
|||
One can simply insert a custom PPM filtering program in the pipe. |
|||
; Extract audio from video |
|||
<source lang=bash> |
|||
# Audio container must support the codec. We try first OGG, then MP3, then fallback to MP4. |
|||
ffmpeg -v warning -i input.mkv -vn -acodec copy output.ogg || |
|||
ffmpeg -v warning -i input.mkv -vn -acodec copy output.mp3 || |
|||
ffmpeg -v warning -i input.mkv -vn -acodec copy output.mp4 |
|||
</source> |
|||
=== x264 === |
|||
To encode in H264. |
|||
This can encode from standard input directly. Say <code>sort</code> produces a PPM video [https://nullprogram.com/blog/2017/11/03/]: |
|||
<source lang="bash"> |
|||
./sort | x264 --fps 60 -o video.mp4 /dev/stdin |
|||
</source> |
|||
== Video Editor == |
|||
=== KDEnLive === |
|||
The best out there. |
|||
=== Flowblade Movie Editor === |
|||
;Install |
|||
<source lang=bash> |
|||
sudo apt install flowblade |
|||
</source> |
|||
* Slow export (8min for 1min video). Encoding in MPEG2. |
|||
: Export '''failed'''. Audio muted after 5 sec. In fact, audio playback was choppy during preview. |
|||
=== Openshot === |
|||
;Status = BAD |
|||
* {{green|update}} — 2019-April: new version out, with positive feedback on Hacker news. To retry? |
|||
* Version 1.4.3 — Made a basic video edit (snip) and export. Works ok but has an annoying bug that video loses start time when editing properties [https://bugs.launchpad.net/openshot/+bug/1119897].in |
|||
: Very fast export (youtube-HD), couple of seconds to export a 1min video. |
|||
* Version 2.3.4 — Video playback does not work. Stop playing after 2 or 3 sec. |
|||
;Ins |
|||
The version distributed in Ubuntu repository is an old version (1.4.3) and has an annoying bug [https://bugs.launchpad.net/openshot/+bug/1119897]. Better install the latest version from dev PPA [http://www.openshot.org/ppa/]. |
|||
<source lang=bash> |
|||
sudo add-apt-repository ppa:openshot.developers/ppa |
|||
sudo apt-get update |
|||
sudo apt-get install openshot-qt |
|||
</source> |
|||
=== Pitivi === |
|||
* Interface sucks. |
|||
* Movie cursor freezes after some min. |
|||
* Awful rendering time (>1h30 for 1min video, simple video clipping). |
|||
== Movie subtitles == |
== Movie subtitles == |
||
Line 105: | Line 241: | ||
* Display webcam video stream with '''mplayer''' [https://help.ubuntu.com/community/Webcam]: |
* Display webcam video stream with '''mplayer''' [https://help.ubuntu.com/community/Webcam]: |
||
mplayer tv:// -tv driver=v4l2:width=640:height=480:device=/dev/video0 |
mplayer tv:// -tv driver=v4l2:width=640:height=480:device=/dev/video0 |
||
== Generate video == |
|||
=== In C === |
|||
See [https://nullprogram.com/blog/2017/11/03/ Render Multimedia in Pure C] (Using PPM). |
|||
== How-To == |
|||
=== Find duplicates === |
|||
* Below (modified from https://ubuntuforums.org/showthread.php?t=1110498). |
|||
* Update: https://github.com/stueja/viddupes |
|||
<source lang=perl> |
|||
#!/usr/bin/perl |
|||
use File::Path; |
|||
# Source: https://ubuntuforums.org/showthread.php?t=1110498 |
|||
# Modified by Xeyownt |
|||
my $ofh = select STDOUT; #Make stdout hot |
|||
$| = 1; |
|||
select STDOUT; |
|||
$getimages = 1000; #render out 1000 images |
|||
$deletefirst = 300; #delete the first 300 |
|||
$totalimages = $getimages - $deletefirst; |
|||
$minmatch = 2; #might use this later (not used now) |
|||
exit unless defined($ARGV[0]); |
|||
$searchdir = "$ARGV[0]"; #directory to scan |
|||
$searchdir = $searchdir . "/" unless $searchdir =~ m/\/$/; |
|||
$basedir = "/tmp/hashchecker/"; #working directory, this directory will get clobbered, make it something uniq in /tmp/ |
|||
$basedir =~ s|/\z||; |
|||
print "Searching '$searchdir'...\n"; |
|||
print "Cleaning up hsh directory '$basedir'...\n"; |
|||
rmtree($basedir); #see, I told you. |
|||
print "Rendering $getimages frame(s), skipping the first $deletefirst. ($totalimages end result)\n"; |
|||
@videofiles=`find "$searchdir" -type f -printf "%p\n" | grep -Ei "\.(mp4|flv|wmv|mov|avi|mpeg|mpg|m4v|mkv|divx|asf)"`; |
|||
foreach $i (@videofiles) |
|||
{ |
|||
chomp $i; |
|||
print "Processing '$i'..."; |
|||
@filename = split(/\//,$i); |
|||
$imgdir = $basedir . "/$filename[-1]"; |
|||
mkpath($imgdir); |
|||
$data=`cd "$imgdir"; mplayer -really-quiet -vo png -frames $getimages -ao null "$i" 2>&1`; |
|||
@data=`find "$imgdir" -type f -name "*.png" | sort`; |
|||
for ($deletecount=0; $deletecount < $deletefirst; $deletecount++) |
|||
{ |
|||
chomp $data[$deletecount]; |
|||
unlink $data[$deletecount]; |
|||
} |
|||
print "mogrify -resize 10x10! -threshold 50% -format bmp \"$imgdir/*\"\n"; |
|||
$data=`mogrify -resize 10x10! -threshold 50% -format bmp "$imgdir/*"`; |
|||
$data=`find "$imgdir" -type f -name "*.png" -delete`; |
|||
print "\n"; |
|||
} |
|||
print "Calculating hash table...\n"; |
|||
@md5table=`find "$basedir" -type f -name "*.bmp" -exec md5sum "{}" \\; | sort | uniq -D -w32`; |
|||
foreach $x (@md5table) |
|||
{ |
|||
chomp $x; |
|||
$x =~ m/^([0-9a-f]{32})/i; |
|||
$md5=$1; |
|||
$x =~ m/^[0-9a-f]{32}[ \t]*(.*)/i; |
|||
$fullpath=$1; |
|||
@filename = split(/\//,$x); |
|||
open (MYFILE, ">>$basedir/$md5.md5") or die "couldnt open file\n"; |
|||
print MYFILE "$fullpath\n"; |
|||
close (MYFILE); |
|||
} |
|||
@hashfiles=`find "$basedir" -type f -name "*.md5"`; |
|||
foreach $i (@hashfiles) |
|||
{ |
|||
chomp $i; |
|||
@uniqfiles=`sort "$i" | uniq`; |
|||
$uniqsize=@uniqfiles; |
|||
if ($uniqsize > 1) |
|||
{ |
|||
$firstpass = 1; |
|||
foreach $x (@uniqfiles) |
|||
{ |
|||
chomp $x; |
|||
@filename=split(/\//,$x); |
|||
if ($firstpass == 1) |
|||
{ |
|||
$outfile=$filename[-2]; |
|||
$firstpass=0; |
|||
} |
|||
else |
|||
{ |
|||
if ($outfile ne $filename[-2]) |
|||
{ |
|||
open (COUNTFILE, ">>$basedir/$outfile.count") or die "$outfile -> couldnt open file\n"; |
|||
print COUNTFILE "$filename[-2]\n"; |
|||
close (COUNTFILE); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
print "Here come the delicious dupes:\n"; |
|||
@hashfiles=`find "$basedir" -type f -name "*.count"`; |
|||
foreach $i (@hashfiles) |
|||
{ |
|||
chomp $i; |
|||
print "$i\n"; |
|||
@uniqfiles=`sort "$i" | uniq -c`; |
|||
foreach $x (@uniqfiles) |
|||
{ |
|||
chomp $x; |
|||
$x =~ m/^[ \t]*([0-9]{1,50})/i; |
|||
$percent = $1/$totalimages*100; |
|||
$x =~ m/^[ \t]*[0-9]{1,50}(.*)/i; |
|||
$filename=$1; |
|||
printf "\t%.2f% match with %s\n",$percent,$filename; |
|||
} |
|||
print "\n"; |
|||
} |
|||
exit; |
|||
</source> |
|||
=== Create video thumbnails === |
|||
==== ffmpegthumbnailer ==== |
|||
Requires {{deb|ffmpegthumbnailer}}: |
|||
<source lang="bash"> |
|||
THUMBDIR=thumbnails |
|||
THUMBSUMMARY=summary.png |
|||
make_thumbnails() |
|||
{ |
|||
if [ -d $THUMBDIR ]; then |
|||
mv $THUMBDIR $THUMBDIR-$(date +"%Y%m%d%H%M%S") |
|||
fi |
|||
# sudo apt install ffmpegthumbnailer |
|||
SIZE=512 |
|||
mkdir -p "$THUMBDIR" |
|||
i=0 |
|||
for f in *; do |
|||
[ "$f" = "$THUMBDIR" ] && continue |
|||
echo -- "$f" |
|||
ffmpegthumbnailer -s $SIZE -i "$f" -o "$THUMBDIR/$f-10.png" -c png -t 10 |
|||
ffmpegthumbnailer -s $SIZE -i "$f" -o "$THUMBDIR/$f-20.png" -c png -t 20 |
|||
((i++)) |
|||
# [ $i -lt 5 ] || break |
|||
done |
|||
echo "Doing montage..." |
|||
montage -label %f -frame 5 -geometry "$SIZEx$SIZE+2+2>" $THUMBDIR/*.png $THUMBSUMMARY |
|||
mv $THUMBSUMMARY $THUMBDIR/ |
|||
} |
|||
</source> |
|||
Note that the thumbnail summary can be quite big. Use viewer like {{deb|feh}} to view it. The same application can be used to view thumbnails easily: |
|||
<source lang="bash"> |
|||
THUMBDIR=thumbnails |
|||
THUMBSUMMARY=summary.png |
|||
view_thumbnails() |
|||
{ |
|||
# sudo apt intall feh |
|||
feh -dF --zoom fill $THUMBDIR |
|||
} |
|||
view_thumbnails_summary() |
|||
{ |
|||
# sudo apt intall feh |
|||
feh $THUMBDIR/$THUMBSUMMARY |
|||
} |
|||
</source> |
|||
==== ffmpeg ==== |
|||
<source lang="bash"> |
|||
ffmpeg -itsoffset -5 -i "$srcimg" -vcodec mjpeg -vframes 1 -an -f rawvideo -s 200x200 -loglevel quiet "$dest" |
|||
</source> |
|||
=== Extracting / Cropping a clip from an MP4 File === |
|||
From [https://superuser.com/questions/446107/extracting-a-clip-from-an-mp4-file-in-linux-on-kubuntu-11-10 superuser.com]: |
|||
<source lang=bash> |
|||
# using avconv: |
|||
avconv -i input.mp4 -ss 00:00:15 -t 00:00:10 -codec copy output.mp4 |
|||
# using ffmpeg: |
|||
ffmpeg -i input.mp4 -ss 00:00:15 -t 00:00:10 -c:v copy -c:a copy output.mp4 |
|||
</source> |
|||
Also works for mp4 in <code>EXT3MU</code> format: |
|||
<source lang=text> |
|||
#EXTM3U |
|||
#EXT-X-TARGETDURATION:11 |
|||
#EXT-X-ALLOW-CACHE:YES |
|||
#EXT-X-PLAYLIST-TYPE:VOD |
|||
#EXT-X-VERSION:3 |
|||
#EXT-X-MEDIA-SEQUENCE:1 |
|||
#EXTINF:5.000, |
|||
http://... |
|||
#EXTINF:10.000, |
|||
http://... |
|||
</source> |
|||
To crop a clip: |
|||
<source lang="bash"> |
|||
# using ffmpeg -- syntax is "width:height:x:y" |
|||
ffmpeg -i input_video.mp4 -filter:v "crop=480:1080:0:0" -c:a copy output_video.mp4 |
|||
</source> |
|||
=== Convert a movie to PNG === |
|||
Use '''ffmpeg''': |
|||
<source lang=bash> |
|||
# -nostdin to avoid ffmpeg to read frmo stdin. Or could do 'echo y | ffmpeg ...' |
|||
ffmpeg -nostdin -i movie.mp4 -r 25 movie%03d.png # -r sets the framerate |
|||
</source> |
|||
=== Reindex a video === |
|||
Use '''ffmpeg''': |
|||
<source lang=bash> |
|||
# -nostdin to avoid ffmpeg to read frmo stdin. Or could do 'echo y | ffmpeg ...' |
|||
ffmpeg -nostdin -i movie.mp4 -codec copy reindexed.mp4 |
|||
</source> |
|||
=== Repair a truncated video === |
|||
;Using ffmpeg |
|||
If problem with the container [https://superuser.com/questions/538829/repairing-corrupt-mp4]: |
|||
<source lang="bash"> |
|||
ffmpeg -i input.mp4 -c copy output.mp4 |
|||
</source> |
|||
;Using untrunc |
|||
If getting message <code>moov atom not found</code>, '''[https://github.com/ponchio/untrunc untrunc]''' can repair truncated video file given a working video file. |
|||
* Repair truncated video on android phone due to unexpected shutdown (battery failure). |
|||
To use: |
|||
* Build using docker: |
|||
<source lang="bash"> |
|||
git clone https://github.com/ponchio/untrunc.git |
|||
cd untrunc |
|||
sudo apt install docker.io |
|||
sudo docker build -t untrunc . |
|||
</source> |
|||
* Run trunc on the truncated video. Assuming these videos are located at {{file|/tmp/broken.mp4}} and {{file|/tmp/working.mp4}}: |
|||
<source lang="bash"> |
|||
cd tmp |
|||
sudo docker run -v /tmp/:/files untrunc /files/working.mp4 /files/broken.mp4 |
|||
</source> |
|||
Process can take several minutes, with lot of spam. |
|||
=== Play PPM video === |
|||
With mpv (mplayer variant), we can play directly giving the FPS [https://nullprogram.com/blog/2017/11/03/]: |
|||
<source lang="bash"> |
|||
./sort | mpv --no-correct-pts --fps=60 - |
|||
</source> |
|||
With VLC, transcode it first: |
|||
<source lang="bash"> |
|||
./sort | ppmtoy4m -F60:1 | vlc - |
|||
</source> |
Latest revision as of 14:34, 2 September 2024
Related Pages
- See Linux sound for Linux sound systems
- See Linux audio for audio support on Linux
- See Linux video for video support on Linux
- See Linux photo for photo support on Linux
- See Dv for capture and conversion of DV tapes.
Play videos
Mplayer
mplayer -ss 30 movie.mp4 # Start playing from 30s
mplayer -ss 01:00 movie.mp4 # Start playing from 01:00 (1 minute)
- External links
- Playing video files
MPlayer plays video files. Many video formats are supported. To play a file:
mplayer <SOMEFILE>
Here a short summary of keyboard shortcuts that can be used during playback:
Key | Function |
---|---|
Left Right | Forward / backward 10 seconds |
Down Up | Forward / backward 1 minutes |
PgDn PgUp | Forward / backward 10 minutes |
Some frequently-used options:
mplayer -xy 2 <SOMEFILE> # Plays a file with a scale factor of 2
- Playing DVD's
Here some handy examples. Mplayer can also be used to play dvd files directly from the harddisk. Check man mplayer
for more examples.
mplayer dvd://1 # Quick start playing dvd from dvd-reader
mplayer dvd://5-7 # Only plays titles 5 to 7
mplayer dvd://1 -dvd-device /path/to/directory/ # Play DVD title 1 from a directory with VOB files
mplayer dvd://1 -alang fr -slang en # Play in Japanese with French subtitles
bug: There is apparently a bug that prevents subtitles to be displayed even though the option -slang is given on the command-line. As a workaround press the key J while playback to cycle through the subtitles.
- Configuring
Edit ~/.mplayer/input.conf [1] (! It's PGDWN !):
RIGHT seek +10 LEFT seek -10 DOWN seek -60 UP seek +60 PGUP seek 600 PGDWN seek -600
mpv
An improved mplayer2.
Record video
Open Broadcaster Software
One of the best free software to record and stream your presentation, live games, etc. A bit difficult to setup, but powerful and excellent results. Linux, Windows, Mac.
# On Debian
sudo apt install ffmpeg obs-studio
SimpleScreenRecorder
SimpleScreenRecorder is a very simple and powerful tool to record desktop on Linux.
- Fullscreen - 128kb mp3, H.264 superfast setting
- Roughly 2Mbps for desktop recording. On i5-4300U CPU @ 1.90GHz, it takes 40% of one core.
VLC
We can use VLC to record the desktop, for instance to make Youtube tutorial videos.
- Go to Media → Convert/ Save
- Select the Capture Device tab
- Set Capture Mode to Desktop.
VLC foresee several profiles:
- H.264 + MP3 (.MP4 container).
- Roughly 1Mbps for desktop recording. On i5-4300U CPU @ 1.90GHz, it takes 95% of one core.
- Youtube SD.
- 640x480 - Roughly 1Mbps for desktop recording. On i5-4300U CPU @ 1.90GHz, it takes 40% of one core.
- Youtube HD.
- Issues
- VLC does not record audio
Encode video
HandBrake
See HandBrake.
ffmpeg
- TROUBLESHOOT - Make sure stdin is dev/null
ffmpeg behaves strangely when stdin is fed with data (e.g. when ffmpeg is run within a while loop reading a file)
# AVOID ffmpeg interactive mode or consuming stdin
ffmpeg ... < /dev/null
- Use yuvj420p to get full 8-bit color range
By default, ffmpeg would use a compressed color range [16,255]. Use pixel format yuvj420p
to get the full color range [2]:
ffmpeg -i source.mp4 -c:v libx265 -pix_fmt yuvj420p dest.mp4
- Rescale video
# Use :-1 to keep aspect ratio - might complain if height is odd
ffmpeg -i input.avi -filter:v scale=720:-1 -c:a copy output.mkv
- Change container
ffmpeg -i input.mkv -c:v copy -c:a copy output.mp4
- Mux video and audio
Say video.mp4 is a h264 flux, and audio.wav is a wave file:
ffmpeg -i video.mp4 -i audio.wav -vcodec copy -acodec mp3 combined.mp4
- Concatenate video (with different codecs)
# https://trac.ffmpeg.org/wiki/Concatenate#differentcodec
# Concatenate
ffmpeg -i file1.mkv -i file2.flv -i file3.mp4 \
-filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4
# Concatenate, but use AAC for output audio
ffmpeg -i file1.mkv -i file2.flv -i file3.mp4 \
-filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa]" \
-c:a aac \
-map "[outv]" -map "[outa]" output.mp4
- Crop video
# Keep leftmost 480x1080 of video
ffmpeg -i input_video.mp4 -filter:v "crop=480:1080:0:0" -c:a copy output_video.mp4
- Custom filtering
This is from Rolling Shutter Simulation in C:
ffmpeg -i input.mp4 -f image2pipe -vcodec ppm pipe:1 | \
x264 -o output.mp4 /dev/stdin
One can simply insert a custom PPM filtering program in the pipe.
- Extract audio from video
# Audio container must support the codec. We try first OGG, then MP3, then fallback to MP4.
ffmpeg -v warning -i input.mkv -vn -acodec copy output.ogg ||
ffmpeg -v warning -i input.mkv -vn -acodec copy output.mp3 ||
ffmpeg -v warning -i input.mkv -vn -acodec copy output.mp4
x264
To encode in H264.
This can encode from standard input directly. Say sort
produces a PPM video [3]:
./sort | x264 --fps 60 -o video.mp4 /dev/stdin
Video Editor
KDEnLive
The best out there.
Flowblade Movie Editor
- Install
sudo apt install flowblade
- Slow export (8min for 1min video). Encoding in MPEG2.
- Export failed. Audio muted after 5 sec. In fact, audio playback was choppy during preview.
Openshot
- Status = BAD
- update — 2019-April: new version out, with positive feedback on Hacker news. To retry?
- Version 1.4.3 — Made a basic video edit (snip) and export. Works ok but has an annoying bug that video loses start time when editing properties [4].in
- Very fast export (youtube-HD), couple of seconds to export a 1min video.
- Version 2.3.4 — Video playback does not work. Stop playing after 2 or 3 sec.
- Ins
The version distributed in Ubuntu repository is an old version (1.4.3) and has an annoying bug [5]. Better install the latest version from dev PPA [6].
sudo add-apt-repository ppa:openshot.developers/ppa
sudo apt-get update
sudo apt-get install openshot-qt
Pitivi
- Interface sucks.
- Movie cursor freezes after some min.
- Awful rendering time (>1h30 for 1min video, simple video clipping).
Movie subtitles
Gnome Subtitles
Gnome Subtitles is an excellent application to generate, or resync subtitles file (format .srt...).
sudo add-apt-repository ppa:pedrocastro/ppa
sudo apt-get update
sudo apt-get install gnome-subtitles
Creating a ScreenCast
From [7]:
- Created an Intrepid instance in VirtualBox.
- Used gtk-recordmydesktop to record only the VirtualBox window.
- Create the intro and outro slides in OOo and recorded them using gtk-recordmydesktop.
- Import all three clips into Pitivi and exported them as a single ogv.
- Recorded the speech in Audacity while watching the screencast and exported it as a wav file.
- Converted the ogv to an avi using mencoder.
- Imported the avi and wav into avidemux, mashed them together and saved an avi.
- Used ffmpeg2theora to convert it back to an ogv.
Another solution: http://wiki.ubuntu.com/ScreencastTeam
Webcam
- Display webcam video stream with mplayer [8]:
mplayer tv:// -tv driver=v4l2:width=640:height=480:device=/dev/video0
Generate video
In C
See Render Multimedia in Pure C (Using PPM).
How-To
Find duplicates
- Below (modified from https://ubuntuforums.org/showthread.php?t=1110498).
- Update: https://github.com/stueja/viddupes
#!/usr/bin/perl
use File::Path;
# Source: https://ubuntuforums.org/showthread.php?t=1110498
# Modified by Xeyownt
my $ofh = select STDOUT; #Make stdout hot
$| = 1;
select STDOUT;
$getimages = 1000; #render out 1000 images
$deletefirst = 300; #delete the first 300
$totalimages = $getimages - $deletefirst;
$minmatch = 2; #might use this later (not used now)
exit unless defined($ARGV[0]);
$searchdir = "$ARGV[0]"; #directory to scan
$searchdir = $searchdir . "/" unless $searchdir =~ m/\/$/;
$basedir = "/tmp/hashchecker/"; #working directory, this directory will get clobbered, make it something uniq in /tmp/
$basedir =~ s|/\z||;
print "Searching '$searchdir'...\n";
print "Cleaning up hsh directory '$basedir'...\n";
rmtree($basedir); #see, I told you.
print "Rendering $getimages frame(s), skipping the first $deletefirst. ($totalimages end result)\n";
@videofiles=`find "$searchdir" -type f -printf "%p\n" | grep -Ei "\.(mp4|flv|wmv|mov|avi|mpeg|mpg|m4v|mkv|divx|asf)"`;
foreach $i (@videofiles)
{
chomp $i;
print "Processing '$i'...";
@filename = split(/\//,$i);
$imgdir = $basedir . "/$filename[-1]";
mkpath($imgdir);
$data=`cd "$imgdir"; mplayer -really-quiet -vo png -frames $getimages -ao null "$i" 2>&1`;
@data=`find "$imgdir" -type f -name "*.png" | sort`;
for ($deletecount=0; $deletecount < $deletefirst; $deletecount++)
{
chomp $data[$deletecount];
unlink $data[$deletecount];
}
print "mogrify -resize 10x10! -threshold 50% -format bmp \"$imgdir/*\"\n";
$data=`mogrify -resize 10x10! -threshold 50% -format bmp "$imgdir/*"`;
$data=`find "$imgdir" -type f -name "*.png" -delete`;
print "\n";
}
print "Calculating hash table...\n";
@md5table=`find "$basedir" -type f -name "*.bmp" -exec md5sum "{}" \\; | sort | uniq -D -w32`;
foreach $x (@md5table)
{
chomp $x;
$x =~ m/^([0-9a-f]{32})/i;
$md5=$1;
$x =~ m/^[0-9a-f]{32}[ \t]*(.*)/i;
$fullpath=$1;
@filename = split(/\//,$x);
open (MYFILE, ">>$basedir/$md5.md5") or die "couldnt open file\n";
print MYFILE "$fullpath\n";
close (MYFILE);
}
@hashfiles=`find "$basedir" -type f -name "*.md5"`;
foreach $i (@hashfiles)
{
chomp $i;
@uniqfiles=`sort "$i" | uniq`;
$uniqsize=@uniqfiles;
if ($uniqsize > 1)
{
$firstpass = 1;
foreach $x (@uniqfiles)
{
chomp $x;
@filename=split(/\//,$x);
if ($firstpass == 1)
{
$outfile=$filename[-2];
$firstpass=0;
}
else
{
if ($outfile ne $filename[-2])
{
open (COUNTFILE, ">>$basedir/$outfile.count") or die "$outfile -> couldnt open file\n";
print COUNTFILE "$filename[-2]\n";
close (COUNTFILE);
}
}
}
}
}
print "Here come the delicious dupes:\n";
@hashfiles=`find "$basedir" -type f -name "*.count"`;
foreach $i (@hashfiles)
{
chomp $i;
print "$i\n";
@uniqfiles=`sort "$i" | uniq -c`;
foreach $x (@uniqfiles)
{
chomp $x;
$x =~ m/^[ \t]*([0-9]{1,50})/i;
$percent = $1/$totalimages*100;
$x =~ m/^[ \t]*[0-9]{1,50}(.*)/i;
$filename=$1;
printf "\t%.2f% match with %s\n",$percent,$filename;
}
print "\n";
}
exit;
Create video thumbnails
ffmpegthumbnailer
Requires ffmpegthumbnailer:
THUMBDIR=thumbnails
THUMBSUMMARY=summary.png
make_thumbnails()
{
if [ -d $THUMBDIR ]; then
mv $THUMBDIR $THUMBDIR-$(date +"%Y%m%d%H%M%S")
fi
# sudo apt install ffmpegthumbnailer
SIZE=512
mkdir -p "$THUMBDIR"
i=0
for f in *; do
[ "$f" = "$THUMBDIR" ] && continue
echo -- "$f"
ffmpegthumbnailer -s $SIZE -i "$f" -o "$THUMBDIR/$f-10.png" -c png -t 10
ffmpegthumbnailer -s $SIZE -i "$f" -o "$THUMBDIR/$f-20.png" -c png -t 20
((i++))
# [ $i -lt 5 ] || break
done
echo "Doing montage..."
montage -label %f -frame 5 -geometry "$SIZEx$SIZE+2+2>" $THUMBDIR/*.png $THUMBSUMMARY
mv $THUMBSUMMARY $THUMBDIR/
}
Note that the thumbnail summary can be quite big. Use viewer like feh to view it. The same application can be used to view thumbnails easily:
THUMBDIR=thumbnails
THUMBSUMMARY=summary.png
view_thumbnails()
{
# sudo apt intall feh
feh -dF --zoom fill $THUMBDIR
}
view_thumbnails_summary()
{
# sudo apt intall feh
feh $THUMBDIR/$THUMBSUMMARY
}
ffmpeg
ffmpeg -itsoffset -5 -i "$srcimg" -vcodec mjpeg -vframes 1 -an -f rawvideo -s 200x200 -loglevel quiet "$dest"
Extracting / Cropping a clip from an MP4 File
From superuser.com:
# using avconv:
avconv -i input.mp4 -ss 00:00:15 -t 00:00:10 -codec copy output.mp4
# using ffmpeg:
ffmpeg -i input.mp4 -ss 00:00:15 -t 00:00:10 -c:v copy -c:a copy output.mp4
Also works for mp4 in EXT3MU
format:
#EXTM3U
#EXT-X-TARGETDURATION:11
#EXT-X-ALLOW-CACHE:YES
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:1
#EXTINF:5.000,
http://...
#EXTINF:10.000,
http://...
To crop a clip:
# using ffmpeg -- syntax is "width:height:x:y"
ffmpeg -i input_video.mp4 -filter:v "crop=480:1080:0:0" -c:a copy output_video.mp4
Convert a movie to PNG
Use ffmpeg:
# -nostdin to avoid ffmpeg to read frmo stdin. Or could do 'echo y | ffmpeg ...'
ffmpeg -nostdin -i movie.mp4 -r 25 movie%03d.png # -r sets the framerate
Reindex a video
Use ffmpeg:
# -nostdin to avoid ffmpeg to read frmo stdin. Or could do 'echo y | ffmpeg ...'
ffmpeg -nostdin -i movie.mp4 -codec copy reindexed.mp4
Repair a truncated video
- Using ffmpeg
If problem with the container [9]:
ffmpeg -i input.mp4 -c copy output.mp4
- Using untrunc
If getting message moov atom not found
, untrunc can repair truncated video file given a working video file.
- Repair truncated video on android phone due to unexpected shutdown (battery failure).
To use:
- Build using docker:
git clone https://github.com/ponchio/untrunc.git
cd untrunc
sudo apt install docker.io
sudo docker build -t untrunc .
- Run trunc on the truncated video. Assuming these videos are located at /tmp/broken.mp4 and /tmp/working.mp4:
cd tmp
sudo docker run -v /tmp/:/files untrunc /files/working.mp4 /files/broken.mp4
Process can take several minutes, with lot of spam.
Play PPM video
With mpv (mplayer variant), we can play directly giving the FPS [10]:
./sort | mpv --no-correct-pts --fps=60 -
With VLC, transcode it first:
./sort | ppmtoy4m -F60:1 | vlc -