Linux video

From miki
Revision as of 13:58, 24 October 2023 by Mip (talk | contribs) (→‎ffmpeg)
Jump to navigation Jump to search

Related Pages

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]:

  1. Created an Intrepid instance in VirtualBox.
  2. Used gtk-recordmydesktop to record only the VirtualBox window.
  3. Create the intro and outro slides in OOo and recorded them using gtk-recordmydesktop.
  4. Import all three clips into Pitivi and exported them as a single ogv.
  5. Recorded the speech in Audacity while watching the screencast and exported it as a wav file.
  6. Converted the ogv to an avi using mencoder.
  7. Imported the avi and wav into avidemux, mashed them together and saved an avi.
  8. 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

#!/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 -