FFmpeg: Extract section of video using MPV screen-shots



An unorthodox, but simple and effective way of accurately extracting a section of video from a larger video file, using MPV screen-shots (with specific file naming scheme) for 'in' and 'out' points.

Bash commands below serve only to demonstrate the general idea. No error handling whatsoever.
#!/bin/bash
# Extract section of video using time-codes taken from MPV screen-shots
# Requires specific MPV screen-shot naming scheme: screenshot-template="%f__%P"
# N.B. Skeleton script demonstrating basic operation

filename="$(ls -1 *.jpg | head -1)"
startTime="$(cut -d. -f-2 <<< "${filename#*__}")"
filename="${filename%__*}"
endTime="$(cut -d_ -f3 <<<"$(ls -1 *.jpg | tail -1)" | cut -d. -f-2)"
ffmpeg \
   -i "$filename" \
   -ss "$startTime" \
   -to "$endTime" \
   "EDIT__${filename}__${startTime}-${endTime}.${filename#*.}"
Another approach to this (and perhaps more sensible) is to script it all through MPV itself. However, that ties the technique down to MPV, whereas, this 'screen-shot' idea allows it to be used with other media players offering timestamps in the filename. Also, it's a little more tangible: you can create a series of screen-shots and later decide which ones are timed better.

video shown in demo: “The Magic of Ballet With Alan and Monica Loughman" DVD (2005)

UPDATE: September 11, 2018



I recently happened upon a MPV lua script created for practical video extraction.


It really works well, and I now find myself using it every time I need to clip a section of video.
link: https://github.com/ekisu/mpv-webm

FFmpeg: Simple video editor with Zenity front-end


A proof-of-concept implementation of a simple, but extensible, video editor, based on FFmpeg with a Zenity interface. Presented as a proof-of-concept as bugs still remain and the project is abandoned.

The goal was to create a video editor with the simplest of requirements; tools found on most popular GNU/Linux distributions, with a standard installation of FFmpeg (+FFplay). The original idea was to create just a video clipping tool, however, the facility to add functionality was included. Extending the functionality involved creating separate scripts with Zenity dialogs relating to the feature added.

While the effectiveness of the implementation is questionable, some interesting concepts remain, such as: a scrub-bar for FFplay created from just a set of filterchains, a novel approach to referencing time-stamps from FFplay, and the correct FFmpeg switches to force edit video clips on non-keyframes (the results of which are demonstrated in the video above).

download: ZenityVideoEditor_0.1.tar.gz

original version: 2016, 15th February https://twitter.com/oioiiooixiii/status/699239047806500864

Filthy Frank: "Pinku Dragon"


The effect was created by first extracting the foreground in Flowblade video editor [the FFmpeg version of this process was demonstraited previously¹]


In the animation, the Flowblade window is shown. The blur amount of a filter on the mask is being altered, which demonstraits the mask area growing and shrinking, and the edges of the mask get fuzzier.

Each cut-out frame was then sequentially merged, and overlayed on a background frame, creating the final animation. However, this was not the original goal of the process. If it were, it may have been easier to create using ImageMagick's stacking functionality²

[ Demonstrating the full procedure involved in foreground extraction using Flowblade may appear in a future blog post ]
¹ see also: https://oioiiooixiii.blogspot.com/2016/09/ffmpeg-extract-foreground-moving.html
² see also: https://oioiiooixiii.blogspot.com/2017/01/long-exposure-photography-compared-to.html
source video: https://www.youtube.com/watch?v=S6bQibFNs2E
original upload: (Twitter) August 5, 2016

Deceptive 2002 'Denny' Euro conversion calculator



Bash: Youtube-dl script which adds channel-id to video filenames

UPDATE: 2020-01-15
# A simple 'youtube-dl' one-liner that can replace everything else the script
youtube-dl "$1" -f 'bestvideo+bestaudio' -o "%(channel_id)s---%(id)s---%(title)s.%(ext)s"

Sometime between publishing this script (including subsequent unpublished versions), and now, 'youtube-dl' has added 'channel_id' as a output filename descriptor, therefore making this code largely defunct.

more info: https://github.com/ytdl-org/youtube-dl#output-template

#!/bin/bash
################################################################################
# Download YouTube video, adding 'channel ID' to downloaded video filename¹
# - Arguments: YouTube URL
# source: https://oioiiooixiii.blogspot.com
# version: 2017.11.26.00.04.10
# - Fixed filename issue where youtube-dl uses "mkv" container  
# -------  2017.11.11.15.19.06
# - Changed 'best (mp4)' to best anything (for vp9 4K video) 
# -------  2017.08.05.22.50.15
################################################################################

# Checks if video already exists in folder (checks YouTube ID in filename)
[ -f *"${1##*=}.m"* ] \
   && echo "*** FILE ALREADY EXISTS - ${1##*=} ***" \
   && exit

# Download html source of YouTube video webpage
html="$(wget -qO- "$1")"

# Extract YouTube channel ID from html source
channelID="$(grep channelId <<<"$html" \
            | tr \" \\n \
            | grep -E UC[-_A-Za-z0-9]{21}[AQgw])"

# Download best version of YouTube video
youtube-dl -f 'bestvideo+bestaudio' \
            --add-metadata \
            "$1"

# Download best (MP4) version of YouTube video
#youtube-dl -f 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best' \
#            --add-metadata \
#            "$1"

# Get filename of video created by youtube-dl
filename="$(find . -maxdepth 1 -name "*${1##*=}.m*" \
            | cut -d\/ -f2)"

# Rename filename
echo "Renaming file to: ${channelID}_${filename}"
mv "$filename" "${channelID}_${filename}"

### NOTES ######################################################################

# ¹2017, May 21: Waiting for this to be implemented in youtube-dl
# youtube-dl -v -f137+140 -o '%(channel_id)s-%(title)s-%(id)s.%(ext)s'
# https://github.com/rg3/youtube-dl/issues/9676
download: ytdl.sh
context: https://github.com/rg3/youtube-dl/issues/9676

【中森明菜】:『少女A』(Akina Nakamori: "Girl A") - 1982, November 25th


source video: https://www.youtube.com/watch?v=kO2meEexNsE

FFmpeg: 144 (16x9) grid of random Limmy Vine videos


It would have been nice to complete this all in one FFmpeg command (building such a command is a relatively trivial 'for loop' affair¹) but the level of file IO made this impossible (for my setup at least). Perhaps with smaller file sizes and fewer videos, it would be less impractical.

# Some basic Bash/FFmpeg notes on the procedures involved: 

# Select random 144 videos from current folder ('sort -R' or 'shuf')
find ./ -name "*.mp4" | sort -R | head -n 144

# Generate 144 '-i' input text for FFmpeg (files being Bash function parameters)
echo '-i "${'{1..144}'}"'
# Or use 'eval' for run-time creation of FFmpeg command
eval "ffmpeg $(echo '-i "${'{1..144}'}"')"

# VIDEO - 10 separate FFmpeg instances

# Create 9 rows of 16 videos with 'hstack', then use these as input for 'vstack'
[0:v][1:v]...[15:v]hstack=16[row1];
[row1][row2]...[row9]vstack=9
# [n:v] Input sources can be omitted from stack filters if all '-i' files used

# AUDIO - 1 FFmpeg instance

# Mix 144 audio tracks into one output (truncate with ':duration=first' option)
amix=inputs=144

# If needed, normalise audio volume in two passes - first analyse audio
-af "volumedetect"
# Then increase volume based on 'max' value, such that 0dB not exceeded 
-af "volume=27dB"

# Mux video and audio into one file
ffmpeg -i video.file -i audio.file -map 0:0 -map 1:0 out.file

# Addendum: Some other thoughts in reflection: Perhaps piping the files to a FFmpeg instance with a 'grid' filter might simplify things, or loading the files, one by one, inside the filtergraph via 'movie=' might be worth investigating. 
¹ See related: https://oioiiooixiii.blogspot.com/2017/01/ffmpeg-generate-image-of-tiled-results.html
context: https://en.wikipedia.org/wiki/Limmy
source videos: https://vine.co/Limmy