UPD-2! Версия с GUI здесь.
UPD! Советы в большей степени касаются первоначальной версии framegrabber.
Обновленная версия (консольного) скрипта и описание к нему здесь!

Иногда возникает необходимость быстро создать серию скриншотов какого-либо видео, желательно аккуратно скомпонованных в одном файле (такое желание естественно например если вы релизите фильм на торрент-трекере).

Под небезызвестной ос windows есть множество утилит, которые с этим успешно справляются (см. Image Grabber 2).
Такого класса программы есть и под Linux, однако они обычно тянут за собой кучу зависимостей в виде библиотек типа xine-lib или того хуже qt4 (как тот же QFrameCatcher).

Я предлагаю вместо этого воспользоваться замечательным скриптом (к сожалению не известного мне автора):


#!/bin/bash
set +x

usage="framegrabber -h for help"
print_help()

{ cat <<'EOF'


Usage : framegrabber [-n stills] [-s size] FILE

Framegrabber is designed to extract stills from a video that is seekable and supported by
Mplayer. Framegrabber then combine them in a mosaic image allowing preview of the movie. Number of frames to extract and size of the frames can be modified via options.

Framegrabber depends on Mplayer and Imagemagick

Options :
-h : print this help message
-n : number of stills to extract
-s : size of each stills

framegrabbing -n 20 -s 100 my_video will create a mosaic of 20 stills of 100 pixels each.



EOF
}

while getopts ":n:s:h" option
do

case $option in
n ) n=$OPTARG;;
s ) s=$OPTARG;;
h ) print_help; exit 1;;
\? ) echo "Unknown option"; echo $usage; exit 1;;
* ) echo "Unknown option"; echo $usage; exit 1;;

esac
done



(( ! n )) && n=20

(( ! s )) && s=150


shift $(($OPTIND - 1))

_NFILE="$1"

_NBFRAME=$n
_SIZEFRAME=$s

_DIR=${_NFILE%/*}
_FILE=${_NFILE##*/}

(( ! $_FILE )) && print_help

cd "$_DIR"
pwd
echo "$_FILE"
mkdir sctmp
_SECONDS=`mplayer -ao null -vo null -frames 1 -identify "$_FILE" | grep ID_LENGTH= | cut -d"=" -f 2`
_FPS=`mplayer -ao null -vo null -frames 1 -identify "$_FILE" | grep ID_VIDEO_FPS= | cut -d"=" -f 2`
_INTSEC=`awk -v var="$_SECONDS" 'BEGIN { rounded = sprintf("%.0f", var); print rounded }'`
_INTFPS=`awk -v var="$_FPS" 'BEGIN { rounded = sprintf("%.0f", var); print rounded }'`
_STEP=`expr "$_INTSEC" / "$_NBFRAME"`
#_STEP=`expr $_STEP2 / $_NBFRAME`
_INTSTEP=`awk -v var="$_STEP" 'BEGIN { rounded = sprintf("%.0f", var); print rounded }'`
_SECSTEP=$_INTSTEP

_MAXFRAME=`expr 100 + $_NBFRAME + 1`

echo $_SECONDS
echo $_FPS
echo $_STEP

for i in `seq 100 $_MAXFRAME`

do
mplayer -really-quiet -ss "$_SECSTEP" -vo jpeg -frames 7 "$_FILE"
_SECSTEP=`expr $_SECSTEP + $_INTSTEP`
mv 00000007.jpg sctmp/$i.jpg
done

rm 0000000*.jpg
pwd
cd sctmp
mogrify -resize "$_SIZEFRAME"x1000 *.jpg
montage -geometry +2+2 -tile 4 *.jpg "$_FILE".png
rm *.jpg
convert "$_FILE".png "$_FILE".jpg
rm *.png
mv "$_FILE".jpg ..
cd ..
rmdir sctmp
echo "Finished"




Скрипт использует mplayer и imagemagick, которые входят в состав любого desktop-ориентированного дистрибутива. Соответственно с поддерживаемыми форматами проблем не предвидится (mplayer).

Использовать его проще простого:
$ framegrabbing -n 8 -s 320 video.avi
, где 8 - количество требуемых скриншотов, а 320 - их размер.

Результат выполнения данной команды должен выглядеть примерно так:

Важно! В скрипте автор с помощью mplayer'а создает по 7 скриншотов за раз и для конечного файла использует именно седьмой, однако mplayer (по крайне мере на некоторых файлах) не всегда выдает все 7. Поэтому имеет смысл брать именно первый скриншот, а имеено следует в строке "mv 00000007.jpg sctmp/$i.jpg" (строка 87) заменить 00000007.jpg на 00000001.jpg, т.е. всегда забирать первый файл.

1 коммент.:

  1. Анонимный комментирует...

    New version with GUI is out : https://sourceforge.net/projects/framegrabgtk/  


 

Copyright © 2007 DamnSmallBlog. Content is licensed under Creative Commons Attribution-Noncommercial.

Design: GeckoandFly and Blogcrowds.