LINUX.ORG.RU

Сгенерировать раскадровку для видеофайла


0

0

Помню, что тема где-то в недрах форума поднималась. Увы не могу найти. Чем можно сделать сабж, mencoder-ом? Да.. еще хотелось бы, чтобы эскизы компоновались в один общий графический файл, а не лежали в папке по отдельности.

★★★

Ну наверное вам поможет скрипт на bash, ffmpeg, imagemagic.

Вот так можно "выдрать" превьюшки:

ffmpeg -i input_video.avi -r 1/100 -s 136x60 -qmin 5 -qmax 5 -b 10k thumb-%03d.jpg

где -s 136×60 - желаемое разрешение превьюшки;
-r 1/100 - каждые 100 секунд;

Можно еще добавить параметры -ss число_секунд для пропуска начала видео, и -t число_секунд для ограничения количества миниатюр.

andreyu ★★★★★
()

как вариант:

$ cat framegrabbing.sh
#!/bin/bash
# Скрипт для получения серии скриншотов к видеофайлу
# http://konishchevdmitry.blogspot.com/

usage=" framegrabber -h for help"
usage_describe="\n
Usage : framegrabber [-n stills] [-s size] files...\n
\n
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.\n
\n
Framegrabber depends on Mplayer and Imagemagick\n
\n
Options:\n
-h : print this help message\n
-n : number of stills to extract (default : 20)\n
-s : size of each stills (default: same as video frame size)\n
\n
framegrabber -n 20 -s 100 my_video will create a mosaic of 20 stills of 100 pixels each."

# Выводит страницу помощи
print_help()
{
 echo -e $usage_describe
}

# Удаляет временные файлы
cleanup()
{
 rm $temp_dir/*.jpg 2>/dev/null
 rmdir $temp_dir
}

# Получаем параметры, заданные пользователем -->
 while getopts ":n:s:h" option
 do
  case $option in
   n ) n=$OPTARG;;
   s ) s=$OPTARG;;
   h ) print_help; exit 0;;
   \? ) echo "Unknown option"; echo $usage; exit 1;;
   * ) echo "Unknown option"; echo $usage; exit 1;;
  esac
 done
# Получаем параметры, заданные пользователем <--

# Значения по умолчанию -->
 ((!n)) && n=20
 ((!s)) && s=0
# Значения по умолчанию <--

shift $(($OPTIND - 1))

# Проверяем, передан ли хотя бы один файл -->
 if [ "$1" == "" ]
 then
  echo $usage
  exit 1
 fi
# Проверяем, передан ли хотя бы один файл <--

# Генерируем скриншоты для каждого переданного файла -->
 while [ "$1" != "" ]
 do
  temp_dir=/tmp/framegrabber_tmp_$$
  old_dir=`pwd`
  file_path="$1"
  frames_num=$n
  frame_size=$s
  file_name=${file_path##*/}

  mkdir $temp_dir || exit 1
  cd $temp_dir || exit 1

  echo "Processing file $file_path..."

  # Получаем абсолютный путь -->
   echo "$file_path" | grep '^/' > /dev/null
   if [ $? -eq 1 ]
   then
    ab_file_path="$old_dir"/"$file_path"
   else
    ab_file_path="$file_path"
   fi
  # Получаем абсолютный путь <--

  # Получаем продолжительность видеофайла -->
   seconds=`mplayer -ao null -vo null -frames 1 -identify "$ab_file_path" 2>/dev/null | \
    grep ID_LENGTH= | cut -d "=" -f 2`
   if [ "$seconds" == "" ]
   then
    echo "mplayer error! May be \"$file_path\" is not a video file?"
    cleanup
    cd $old_dir
    shift
    continue
   fi
   seconds=`awk -v var="$seconds" 'BEGIN { rounded = sprintf("%.0f", var); print rounded }'`
  # Получаем продолжительность видеофайла <--

  # Количество секунд, через которое мы будем перепрыгивать для получения очередного скриншота -->
   step=`expr $frames_num + 1`
   step=`expr $seconds / $step`
   step=`awk -v var=$step 'BEGIN { rounded = sprintf("%.0f", var); print rounded }'`
  # Количество секунд, через которое мы будем перепрыгивать для получения очередного скриншота <--

  # Генерируем необходимое количество скриншотов -->
   is_error=0
   cur_sec=$step
   max_image_file_name=`expr 100 + $frames_num - 1`
   for image_file_name in `seq 100 $max_image_file_name`
   do
    mplayer -ao null -ss $cur_sec -vo jpeg -frames 30 "$ab_file_path" > /dev/null 2>&1
    mv 00000007.jpg $image_file_name.jpg 2>/dev/null
    if [ $? -ne 0 ]
    then
     is_error=1
     break
    fi
    rm 000000??.jpg
    cur_sec=`expr $cur_sec + $step`
   done
   
   if [ $is_error -ne 0 ]
   then
    echo "mplayer error! May be \"$file_path\" is not a video file?"
    cleanup
    cd $old_dir
    shift
    continue
   fi
  # Генерируем необходимое количество скриншотов <--

  cd $old_dir

  # Подбираем оптимальное количество кадров в строке -->
   if [ `expr $frames_num % 4` -eq 0 ]
   then
    hor_frames_num=4
   else
    if [ `expr $frames_num % 3` -eq 0 ]
    then
     hor_frames_num=3
    else
     if [ `expr $frames_num % 2` -eq 0 ]
     then
      hor_frames_num=2
     else
      hor_frames_num=4
     fi
    fi
   fi
  # Подбираем оптимальное количество кадров в строке <--

  # Упаковываем все захваченные кадры в один файл -->
   if [ $frame_size -ne 0 ]
   then
    resize_option="-resize $frame_size"
   else
    resize_option=""
   fi
   montage $resize_option -geometry +2+2 -tile $hor_frames_num -quality 100 $temp_dir/*.jpg "$file_name".jpg
  # Упаковываем все захваченные кадры в один файл <--

  cleanup
  
  # Прыгаем на следующий в списке файл
  shift
 done
# Генерируем скриншоты для каждого переданного файла <--

echo "Finished"

dGhost ★★★
()

Спасибо вышеотписавшимся, буду эксперементировать :)

Amp ★★★
() автор топика
Ответ на: комментарий от Cy6erBr4in

Провинциальные тарифы на интернет оставляют желать лучшего и злобные трэкеры меня поэтому интересуют не сильно, а уж тем более раздача на них :)

Amp ★★★
() автор топика
Ответ на: комментарий от dGhost

# Удаляет временные файлы
cleanup()
{
rm $temp_dir/*.jpg 2>/dev/null
rmdir $temp_dir
}

Так тут же убьются все *.jpg, вашей ли это утилиты или чужой.

andreyu ★★★★★
()
Ответ на: комментарий от dGhost

Спасибо за скрипт. Но есть вопрос.

> mv 00000007.jpg $image_file_name.jpg 2>/dev/null

Почему выбран именно 7-й файл в последовательности? Не лучше ли брать базовый кадр?

картинка: dearall :) не шучу.

anonymous
()
Ответ на: комментарий от anonymous

> Спасибо за скрипт.

Не хватает индикатора прогресса. Это feature request :)

anonymous
()
Ответ на: комментарий от andreyu

> Так тут же убьются все *.jpg, вашей ли это утилиты или чужой.

temp_dir=/tmp/framegrabber_tmp_$$ !!

> Почему выбран именно 7-й файл в последовательности? Не лучше ли брать базовый кадр

лучше это спросить у автора скрипта, адрес его блога в самом начале

dGhost ★★★
()

А у меня такой вопрос. Стандарты на сжатие подразумевают ключевые кадры (в МПЕГ 4 - точно). Думается, что извлечение таких кадров должно было бы происходить очень быстро! А вот как их распознать и вытащить?

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.