Форум русскоязычного сообщества Ubuntu


Считаете, что Ubuntu недостаточно дружелюбна к новичкам?
Помогите создать новое Руководство для новичков!

Автор Тема: Bash FFmpeg Mencoder Конвертирование mp4 в avi массовая склейка видео без потерь  (Прочитано 8198 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Morecc-Puppai

  • Автор темы
  • Новичок
  • *
  • Сообщений: 13
  • Ubuntu 12.04 - AMD64
    • Просмотр профиля
    • Деньги до зарплаты
 :( думал в понедельник приду, и в теме скриптик будет..

Оффлайн peregrine

  • FSM
  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 7215
  • Gentoo x64 Ubuntu 16.04.1 x64
    • Просмотр профиля
Morecc-Puppai, был занят. Кое-что нагуглил по вашей проблеме. Всё можно сделать при помощи одного ffmpeg. Главное - разобраться с путями. Вы руками можете создать каталоги с названиями точек в папке Архив? Жалательно, чтоб они назывались так: Точка x Бла-бла-бла, где важно лишь то, что имя точки начинается со слов Точка x , а дальше, через пробел любые символы. x - любое число. И желательно, чтоб других файлов и папок в каталоге с точками и архивом не было.

Оффлайн Morecc-Puppai

  • Автор темы
  • Новичок
  • *
  • Сообщений: 13
  • Ubuntu 12.04 - AMD64
    • Просмотр профиля
    • Деньги до зарплаты
peregrine,
Могу поправить пути сам - не проблема. Папок в каталоге больше не будет.
Цитировать
Вы руками можете создать каталоги с названиями точек в папке Архив?
да могу
Огромное спасибо,Перегирн, за потраченное время. Очень признателен и благодарен! Где кнопка "плюсануть"  :)

Пользователь решил продолжить мысль 14 Августа 2013, 13:01:46:
Уточнение:
-Как будет логичнее сделать, - сначала склеить фрагменты в mp4 формате, а затем перекодировать, или сначала перекодировать все mp4 в (mkv,flv - что лучше) а потом только склеить?
« Последнее редактирование: 14 Августа 2013, 13:01:46 от Morecc-Puppai »

Оффлайн peregrine

  • FSM
  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 7215
  • Gentoo x64 Ubuntu 16.04.1 x64
    • Просмотр профиля
Morecc-Puppai, извиняюсь за скрипт, сейчас самому надо десяток написать, так что времени нет и не предвидится.
Вот что нашёл,надеюсь хоть как-то поможет.
http://ffmpeg.org/trac/ffmpeg/wiki/How%20to%20concatenate%20%28join,%20merge%29%20media%20files
Там есть демуксер contact
если записать строку вида:
ffmpeg -f concat -i mylist.txt -c copy output.avi
Должно всё получиться по-идее.
в файле mylist.txt должны быть имена файлов в нужной последовательности (mp4 попробуйте, может и конвертнёт и склеит сразу), возможно, вместо файла можно использовать переменную.

Оффлайн san-alex

  • Забанен
  • Старожил
  • *
  • Сообщений: 7726
  • Ex-CNC programmer
    • Просмотр профиля
Если еще интересует склейка авишек, недавно нашел интересную статью
Оказывается их можно просто закинуть в один файл:
cat fille01.avi file02.avi file03.avi > file00.aviи с помощью mencoder перестроить индекс
mencoder -forceidx -oac copy -ovc copy file00.avi -o file.aviПопробовал - получилось и достаточно быстро сработало.

Оффлайн Morecc-Puppai

  • Автор темы
  • Новичок
  • *
  • Сообщений: 13
  • Ubuntu 12.04 - AMD64
    • Просмотр профиля
    • Деньги до зарплаты
peregrine,Сейчас буду пытаться делать код, который автоматом будет добавлять имена файлов (соблюдая последовательность) в папке с фрагментами и добавлять их в этот файлик

Изучаю BASH с нуля. (Читаю тут - http://habrahabr.ru/post/47915/ и тут - http://www.opennet.ru/docs/RUS/bash_scripting_guide/x1716.html)

san-alex, читал эту статью. Мне нужен скрипт чтобы это делать массово а не вручную

Вот нагугленые варианты склейки:
mencoder -ovc copy -oac copy -o out.avi 1.avi 2.avi - склеить MENCODER'ом несколько avi

avimerge -i input1.avi input2.avi -o new_input12.avi - ещё вариант склейки AVIMERG'ем

ffmpeg -i "concat:mov1.ts|mov2.ts" -vcodec copy -acodec copy output.mp4- склейка через ffmpeg, исходный контейнер ts (mp4 клеить сам не пробовал)

cat 1.avi 2.avi 3.avi 4.avi 5.avi 6.avi > outfile.avi - склейка CAT'ом (но, как уже писал san-alex,после склейки нужно делать переиндексирование конечного файла через mencoder, пост выше)

http://goo.gl/jXcfmG - тут мануал на англицком по ffmpeg (официальный)

Остаётся только автоматизировать перекодирование через циклы и операторы проверки условий

Цитировать
в файле mylist.txt должны быть имена файлов в нужной последовательности
Не вариант Руками вбивать каждый день в этот файлик новые появившиеся имена, потому как за день их появляется более тысячи.
- http://barbar.ru/?p=254 - Тут нашёл то, что искал! Датировано 2011 годом!, код одной строкой:

for invideo in `find -name '*.MTS'`; do ffmpeg -i $invideo -deinterlace -target pal-dvd Converted/${invideo%%.MTS}.avi; done; mencoder -ovc copy -oac copy -o Converted/outvideo.avi Converted/*.aviПояснение кода выше:
(Нажмите, чтобы показать/скрыть)
Тут меняем контейнеры MTS и AVI на нужные
« Последнее редактирование: 19 Августа 2013, 14:54:01 от Morecc-Puppai »

Оффлайн victor00000

  • Старожил
  • *
  • Сообщений: 15568
  • Глухонемой (Deaf)
    • Просмотр профиля
Video Fixer для Win

mencoder -forceidx -oac copy -ovc copy video.avi -o fixedvideo.aviдля Lin
Wars ~.o

Оффлайн Morecc-Puppai

  • Автор темы
  • Новичок
  • *
  • Сообщений: 13
  • Ubuntu 12.04 - AMD64
    • Просмотр профиля
    • Деньги до зарплаты
В общем сделал сам основную часть, помогите доработать:
#!/bin/bash
cd /home/simon/Рабочий\ стол/test
#смена каталога
path=/home/simon/Рабочий\ стол/test/
arhiv=$path/arhiv/
#объявление переменных
touch $path/log.txt
#создаём лог
ls -d */ -l | grep -v arhiv | awk '{print $9}' > $path/log.txt
#вывод списка имен директорий (Кроме папки Архив) с камерами построчно и парсинг сохраняем в лог-файл
cols=$(cat $path/log.txt | wc -l)
#присвоение переменной $cols значение числа строк
N=0
#назначение переменной равной числу первой строки из лога
$tochkaN ${}
#создаём пустой массив
until [ "$N" -eq "$cols" ]
#Открываем условный цикл, с уловием, пока переменная $N не станет равна числу строк в логе $cols
do
echo ${tochka[$N]}=(cut $path/log.txt | awk '{print $N}' | если имя папки с пробелами, экранировать)
#создать элемент массива с именем ${tochka[$N]}=значение строчки $N из лога
let $N+=1
#присвоить переменной $N значение равное "Число предыдущей строки + 1"
done
#условный цикл закончен
for $tochkaN in ${tochka*}
do запуск скрипта mkdir.sh
done
#выполнение цикла для каждого элемена массива
rm $path/log.txt
#удаляем лог
exit 0

Вот это нужно доработать.
cols=$(cat $path/log.txt | wc -l)   -  как присвоить  переменной $cols число а не процесс выполнения cat (CAT считает количество строк кода текстового файла)?

$tochkaN ${}
#создаём пустой массив  - Не правильно создан пустой массив?
until [ "$N" -eq "$cols" ]
#Открываем условный цикл, с уловием, пока переменная $N не станет равна числу строк в логе $cols
do
echo ${tochka[$N]}=(cut $path/log.txt | awk '{print $N}')
#создать элемент массива $tochkaN с именем tochka[$N]=значение строчки $N из лога
let $N+=1
#присвоить переменной $N значение равное "Число предыдущей строки + 1"
done
#условный цикл закончен
for массива in все элементы массива - какая тут семантика ?
do запуск скрипта mkdir.sh


Скрипт mkdir.sh лежит отдельно (как объеденить скрипты?).
############################ НАЧАЛО ЦИКЛА ############################
cd $path/${tochka[$N]}
#Смена каталога
if ! [ -d $path/${tochka[$N]}/Converted ];
then --
else mkdir "$path/${tochka[$N]}/Converted"
fi
#Создаём папку Converted если её нет
if ! [ -d $arhiv/${tochka[$N]}/ ];
then --
else mkdir $arhiv/${tochka[$N]}/
fi
#Создаём папку $arhiv/${tochka[$N]} если её нет
#Проверяем есть ли в этом каталоге папка Converted, если нет то создаём её
for invideo in `find -name '*.mp4'`; do ffmpeg -i $invideo -deinterlace -target pal-dvd Converted/${invideo%%.mp4}.avi; done;
#Конвертируем все mp4 фрагменты в avi через ffmpeg в папку 'Converted' (Поправить кодирование, чтобы занимало меньше места)
mencoder -ovc copy -oac copy -o Converted/$(date +%d-%m-%Y)-${tochka[$N]}.avi Converted/*.avi
#Склеиваем avi фрагменты в файл папки 'Converted'
mv $path/${tochka[$N]}/Converted/*.avi $arhiv/${tochka[$N]}/
#Перемещаем в архив склееный, сконвертированный файл
rm $path/${tochka[$N]}/*.mp4
#Чистим папку 'to4ka1' от фрагментов mp4
rm $path/${tochka[$N]}/Converted/*.avi
#Чистим папку 'Converted' от фрагментов avi
cd $path/
#Возвращаемся в исходный каталог
############################ КОНЕЦ ЦИКЛА ############################

В итоге должен получится скрипт, который конвертирует и склеивает множество видео фрагментов. Если названия папок с пробелами, то нужно сделать автоматическое экранирование пробелов. Единственное что смущает это размер итогового файла, он в несколько раз превышает совокупный объём фрагментов, но я думаю это решается с помощью настроек FFMPEG
« Последнее редактирование: 29 Августа 2013, 13:27:45 от Morecc-Puppai »

Оффлайн Morecc-Puppai

  • Автор темы
  • Новичок
  • *
  • Сообщений: 13
  • Ubuntu 12.04 - AMD64
    • Просмотр профиля
    • Деньги до зарплаты
Спасибо всем кто не помог, именно благодаря Вам я справился САМ!

#!/bin/bash
#/home/simon/VIDEO_ARHIV
readonly path=/home/simon/video/test
readonly arhiv=$path/Архив
readonly log=log.txt
day=$((`date +%d`-1))
#объявление переменных для путей
N=1
#объявление переменной равной номеру первой строки из лога
cols=`cat $path/$log | wc -l`
#присвоение переменной $cols значения числа строк лога
cd $path
#смена каталога
ls -d */ -l | grep -v Архив | awk '{print $9}' | sed 's/[ \t]*$//' | sed 's/[/\t]*$//' > $path/$log
#вывести спиcок имён папок в лог, удалив в конце пробелы и слэши
tochka=()
#создаём пустой массив
until [ "$N" -gt "$cols" ]
#открываем условный цикл, с уловием, пока переменная $N не станет больше числа строк в логе
do tochka=( "${tochka[@]}" "${tochka[$N]}" )
#добавить новый элемент массива
tochka[$N]=$(cat ${path}/$log | sed -n "$N"p)
#присвоить ему значение строки $N из лога
tchk=${tochka[$N]}
#сделаем переменную покороче
if ! [ -d $path/$tchk/Converted ]
then mkdir $path/$tchk/Converted
else :
fi
#создать папку Converted
cd $path/$tchk
#Смена каталога
for invideo in `find -name '*.mp4'`; do cat $invideo > Converted/${invideo%%.mp4}.avi; done;
#Конвертируем фрагменты в avi в папку 'Converted'
cd $path/$tchk/Converted
for invideo in `find -name '*.avi'`; do mencoder -ovc copy $invideo -o $day-$(date +%m-%Y)-$tchk.avi; done;
#Склеиваем avi фрагменты без аудио в единый файл
if ! [ -d $arhiv/$tchk ]
then mkdir $arhiv/$tchk
else :
fi
#Создаём папку Архив/Точка если её нет
mv $path/$tchk/Converted/*$tchk.avi $arhiv/$tchk
#Перемещаем архив склееный, сконвертированный файл
#rm $path/$tchk/*
#rm $path/$tchk/Converted/*
#Чистим папки от фрагментов
let N=N+1
#переход на новую строчку лога и возврат в начало цикла
done
#rm $path/$log
exit 0

Склеивание происходит только в  mpg avi или raw - mp4 сразу склеить не получится. Без потери качества, быстрее и лучше конвертировать фрагменты CAT 'ом + не происходит увеличение размера файла. Скрипт будет автоматом запускаться через крон в 00.00 поэтому я создал переменную $day, дабы правильно указать день сохранённого видео. Пути не должны содержать пробелов. Фрагменты должны иметь одинаковое разрешение контейнер и кодек. Пользуйтесь кому надо на здоровье
« Последнее редактирование: 30 Августа 2013, 16:41:26 от Morecc-Puppai »

 

Страница сгенерирована за 0.018 секунд. Запросов: 22.