LinuxForum.Fans
Тема

bash скрипт пакетная обработка *.MTS файлов

Автор: neonii 10 сообщений 7033 просмотров
#259078

Участники прошу помощи и совета.
Я новичок. Делаю первые шаги.

Вопрос вот в чем:
Автоматизирую сортировку и перегонку видеофайлов со своей зеркалки.
Фотоаппарат видео пишет в формате MTS(AVCHD)
Сделал при подключении автоматическое монтирование и копирование файлов с SD карты в каталог /home/user/tmp при этом файлы .*MTS копируются в /home/user/tmp/video

Файлы имеют имена 00000.MTS 00001.MTS ...... и т.д.

Нужен скрипт который ищет *.MTS в директории /home/user/tmp/video, преобразует файлы в avi, склеивает их по дате создания (за день), полученный avi файл должен иметь имя типа 14июнь2012.avi и храниться в папке /home/user/video

Скрипт думается мне не сложный
Посмотрел как люди сортируют фотки переделать под свои нужды
получилось вот что:

text
#!/bin/bash

SOURCE=/home/user/tmp # исходная папка TARGET=/home/user/video # папка для копирования

find $SOURCE -iname "*.MTS" | while read FILE ; do DIR=$(ls -lR "$FILE" | awk '{print $7"-"$6"-"$8}') ; test -d $TARGET/$DIR || mkdir $TARGET/$DIR ;

for filename in *.MTS do fname="${DIR}-`basename $filename`" ffmpeg -i ./$filename -r 30 -s 1280x720 -vcodec libxvid -b 18300k -acodec libmp3lame -ab 192k -ac 2 -ar 48000 ./${fname%MTS}avi cp -uv --preserve ./${fname%MTS}avi $TARGET/$DIR; done

Результат скрипта создается одна директория например /home/user/video/17мая2012 и туда ложатся перекодированные файлы вида 17мая2012-00001.avi
Я так понимаю у меня в цикле где-то косяк и он считывает дату с первого файла и всем ее подставляет. Склейки тут нет.

Еще посмотрел как люди в одной папке сразу преобразуют в avi а затем их склеивают одной командой
Вот команда:

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

Несколько дней мытарств ни к чему меня не привели. Никак ума не приложу как как это все объединить в один скрипт.

Пользуйтесь тегом code. Fat-Zer

#259087
"neonii" написал:
DIR=$(ls -lR "$FILE" | awk '{print $7"-"$6"-"$8}') ;

ключ -R тут излишен.
+ как вариант, можно state и date'ом отформатировать дату - красивее будет.

"neonii" написал:
test -d $TARGET/$DIR ||
mkdir $TARGET/$DIR ;

вместо этого лучше просто mkdir -p $TARGET/$DIR

"neonii" написал:
Результат скрипта создается одна директория например /home/user/video/17мая2012 и туда ложатся перекодированные файлы  вида 17мая2012-00001.avi

проверьте сами, ручками, какое время стоит на файлах в ls -l /home/user/tmp
и ещё не хватает done после первого цикла... может я его случайно подтёр, когда малость отформатировал код.
да и второй цикл вообще не нужен...
в итоге должно получиться что-то вроде этого:

text

#!/bin/bash

SOURCE=/home/user/tmp # исходная папка TARGET=/home/user/video # папка для копирования

find $SOURCE -iname "*.MTS" | while read FILE ; do DIR=$(ls -l "$FILE" | awk '{print $7"-"$6"-"$8}') ; mkdir -p $TARGET/$DIR ;

fname="${DIR}-$(basename $FILE)" ffmpeg -i ./$FILE -r 30 -s 1280x720 -vcodec libxvid -b 18300k -acodec libmp3lame -ab 192k -ac 2 -ar 48000 ./${fname%MTS}avi cp -uv --preserve ./${fname%MTS}avi $TARGET/$DIR; done

#259094

Fat-Zer спасибо

"Fat-Zer" написал:
проверьте сами, ручками, какое время стоит на файлах в ls -l /home/user/tmp

ls -l > file.txt
вывел

text
 итого 5719600
-rwxr-xr-x 1 root root  40108032 мая   17  2011 00000.MTS
-rwxr-xr-x 1 root root  26247168 мая   17  2011 00001.MTS
-rwxr-xr-x 1 root root  98795520 мая   17  2011 00002.MTS
-rwxr-xr-x 1 root root 143425536 мая   17  2011 00003.MTS
-rwxr-xr-x 1 root root  52985856 мая   17  2011 00004.MTS
-rwxr-xr-x 1 root root  32931840 мая   17  2011 00005.MTS
-rwxr-xr-x 1 root root  97615872 мая   17  2011 00006.MTS
-rwxr-xr-x 1 root root  56426496 мая   17  2011 00007.MTS
-rwxr-xr-x 1 root root  18481152 мая   17  2011 00008.MTS
-rwxr-xr-x 1 root root  23887872 мая   17  2011 00009.MTS
-rwxr-xr-x 1 root root  11698176 мая   17  2011 00010.MTS
-rwxr-xr-x 1 root root  27426816 мая   17  2011 00011.MTS
-rwxr-xr-x 1 root root  34013184 мая   17  2011 00012.MTS
-rwxr-xr-x 1 root root  42958848 мая   17  2011 00013.MTS
-rwxr-xr-x 1 root root  10616832 мая   17  2011 00014.MTS
-rwxr-xr-x 1 root root   3145728 мая   17  2011 00015.MTS
-rwxr-xr-x 1 root root  45219840 мая   17  2011 00016.MTS
-rwxr-xr-x 1 root root  57409536 мая   17  2011 00017.MTS
-rwxr-xr-x 1 root root  54067200 мая   17  2011 00018.MTS
-rwxr-xr-x 1 root root  44138496 мая   17  2011 00019.MTS
-rwxr-xr-x 1 root root  46301184 мая   17  2011 00020.MTS
-rwxr-xr-x 1 root root 229343232 мая   17  2011 00021.MTS
-rwxr-xr-x 1 root root 620986368 мая   17  2011 00022.MTS
-rwxr-xr-x 1 root root  36274176 мая   17  2011 00023.MTS
-rwxr-xr-x 1 root root 103219200 мая   17  2011 00024.MTS
-rwxr-xr-x 1 root root  42958848 мая   17  2011 00025.MTS
-rwxr-xr-x 1 root root  92110848 мая   17  2011 00026.MTS
-rwxr-xr-x 1 root root  70877184 мая   17  2011 00027.MTS
-rwxr-xr-x 1 root root 298549248 мая   17  2011 00028.MTS
-rwxr-xr-x 1 root root  45121536 мая   17  2011 00029.MTS
-rwxr-xr-x 1 root root 199163904 мая   17  2011 00030.MTS
-rwxr-xr-x 1 root root  66453504 мая   17  2011 00031.MTS
-rwxr-xr-x 1 root root 191397888 мая   17  2011 00032.MTS
-rwxr-xr-x 1 root root 146669568 июня  16  2011 00033.MTS
-rwxr-xr-x 1 root root  92110848 июня  16  2011 00034.MTS
-rwxr-xr-x 1 root root 561807360 дек.  11  2011 00035.MTS
-rwxr-xr-x 1 root root   3047424 дек.  12  2011 00036.MTS
-rwxr-xr-x 1 root root  47480832 янв.   7 19:46 00037.MTS
-rwxr-xr-x 1 root root  10616832 янв.   8 00:27 00038.MTS
-rwxr-xr-x 1 root root  80904192 янв.   8 17:05 00039.MTS
-rwxr-xr-x 1 root root  63012864 янв.   8 19:00 00040.MTS
-rwxr-xr-x 1 root root  55148544 янв.   8 19:01 00041.MTS
-rwxr-xr-x 1 root root  69697536 янв.   8 19:15 00042.MTS
-rwxr-xr-x 1 root root  28409856 янв.   8 19:16 00043.MTS
-rwxr-xr-x 1 root root  63012864 янв.   8 19:16 00044.MTS
-rwxr-xr-x 1 root root  77463552 янв.   8 22:08 00045.MTS
-rwxr-xr-x 1 root root  67534848 янв.  21 16:58 00046.MTS
-rwxr-xr-x 1 root root 396754944 июня  11 19:03 00047.MTS
-rwxr-xr-x 1 root root  36274176 июня  11 19:06 00048.MTS

формат даты почему-то у файлов разные

"Fat-Zer" написал:
+ как вариант, можно state и date'ом отформатировать дату - красивее будет.

как можно этим воспользоваться?

результат работы скрипта после вашей правки

text
 user@server:/home/user/video# ls -l > text2.txt 
text

итого 20
drwxr-xr-x 2 root root 4096 июня  15 00:03 11-июня-19:06
drwxr-xr-x 2 root root 4096 июня  15 00:01 17-мая-2011
drwxr-xr-x 2 root root 4096 июня  15 00:01 8-янв.-00:27
drwxr-xr-x 2 root root 4096 июня  15 00:03 8-янв.-17:05
drwxr-xr-x 2 root root 4096 июня  14 23:55 8-янв.-19:01

и т.д. результат не весь скрипт еще работал!
в папках файлы формата "дата как у директории"-00001.avi ...

И далее как заменить в скрипте вот это

text

 ffmpeg -i ./$FILE -r 30 -s 1280x720 -vcodec libxvid -b 18300k -acodec libmp3lame -ab 192k -ac 2 -ar 48000 ./${fname%MTS}avi

На что-то типа этого?

text

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 

Эта строка содержит несколько идущих подряд команд:

1) for invideo in `find -name ‘*.MTS’`; (находим в папке все файлы с расширением MTS)

2) do ffmpeg -i $invideo -deinterlace -target pal-dvd Converted/${invideo%%.MTS}.avi; (поочердно, конвертируем найденые файлы в формат “avi” и сохраняем в папкe “Converted” с прежним названием но с расширением “avi”)

3) done; (завершаем цикл конвертирования файлов из “MTS” (”AVCHD”) в “AVI”)

4) mencoder -ovc copy -oac copy -o Converted/outvideo.avi Converted/*.avi (исользуя “mencoder” в папке “Converted” склеиваем все файлы с расширением “avi” в новый файл “outvideo.avi”)

то есть объединить все видео файлы созданные в один день в один фильм.avi

#259107
"neonii" написал:
формат даты почему-то у файлов разные

ls для людей делался, а не для машин... если год текущий, то указывается время...

"neonii" написал:
как можно этим воспользоваться?

как-то так:
date -d "$(stat -c=%z 1.c)" "+%Y-%m-%d"
man date для того как форматная строка записывается...
ещё можно было бы выдрать из метаданных самого видео информацию, но это уже другая история...

остальное - попозже... там надо /dev/brain включать...
[added]

"neonii" написал:
И далее как заменить в скрипте вот это

ну собственно первая часть - просто перекодировка... тоже самое, что и в первом случае... только параметры другие, но в видео и кодеках я уже не разбираюсь...
а вторая часть - слияние. т.е. в конец просто ещё один цикл добавить надо:

text
find "$TARGET" -maxdepth 1 | while read DIR ; do 
  mencoder -ovc copy -oac copy -o "$TARGET/$DIR.avi" $TARGET/$DIR/*.avi)
done
#259138

Сегодня еще раз запустил скрипт.

"Fat-Zer" написал:
в итоге должно получиться что-то вроде этого:
text

#!/bin/bash

SOURCE=/home/user/tmp # исходная папка TARGET=/home/user/video # папка для копирования

find $SOURCE -iname "*.MTS" | while read FILE ; do DIR=$(ls -l "$FILE" | awk '{print $7"-"$6"-"$8}') ; mkdir -p $TARGET/$DIR ;

fname="${DIR}-$(basename $FILE)" ffmpeg -i ./$FILE -r 30 -s 1280x720 -vcodec libxvid -b 18300k -acodec libmp3lame -ab 192k -ac 2 -ar 48000 ./${fname%MTS}avi cp -uv --preserve ./${fname%MTS}avi $TARGET/$DIR; done

Вываливается ошибка:

text

cp: не удалось выполнить stat для «./11-июня-19:03-00047.avi»: Нет такого файла или каталога

и для других файлов тоже.
Вчера этот же код работал. Результат я писал.
Я правда с этим

"Fat-Zer" написал:
date -d "$(stat -c=%z 1.c)" "+%Y-%m-%d"
немного поэкспериментировал

Пока никак не врублюсь
понимаю что где то вот тут

DIR=$(ls -l "$FILE" | awk '{print $7"-"$6"-"$8}') ;

вот это нужно

"Fat-Zer" написал:
date -d "$(stat -c=%z 1.c)" "+%Y-%m-%d"
#259146

С этим разобрался

"neonii" написал:
Вываливается ошибка:
text
cp: не удалось выполнить stat для «./11-июня-19:03-00047.avi»: Нет такого файла или каталога 

и для других файлов тоже.

вот это

"neonii" написал:
ffmpeg -i ./$FILE -r 30 -s 1280x720 -vcodec libxvid -b 18300k -acodec libmp3lame -ab 192k -ac 2 -ar 48000 ./${fname%MTS}avi

заменил на

text
ffmpeg -i $FILE -r 30 -s 1280x720 -vcodec libxvid -b 18300k -acodec libmp3lame -ab 192k -ac 2 -ar 48000 ./${fname%MTS}avi

добавил в конец второй цикл по слиянию

text

#!/bin/bash

SOURCE=/home/user/tmp/video # исходная папка TARGET=/home/user/video # папка для копирования

find $SOURCE -iname "*.MTS" | while read FILE ; do DIR=$(ls -l "$FILE" | awk '{print $7"-"$6"-"$8}') ; mkdir -p $TARGET/$DIR ;

fname="${DIR}-$(basename $FILE)" ffmpeg -i $FILE -r 30 -s 1280x720 -vcodec libxvid -b 18300k -acodec libmp3lame -ab 192k -ac 2 -ar 48000 ./${fname%MTS}avi cp -uv --preserve ./${fname%MTS}avi $TARGET/$DIR; done find "$TARGET" -maxdepth 1 | while read DIR ; do mencoder -ovc copy -oac copy -o "$TARGET/$DIR.avi" $TARGET/$DIR/*.avi) done

получаю

text

/home/user/sortvideo.sh: строка 17: ошибка синтаксиса около неожиданной лексемы `)'
/home/user/sortvideo.sh: строка 17: `  mencoder -ovc copy -oac copy -o "$TARGET/$DIR.avi" $TARGET/$DIR/*.avi)'

и с датой

"Fat-Zer" написал:
date -d "$(stat -c=%z 1.c)" "+%Y-%m-%d"

тоже пока непонятно

#259151
"neonii" написал:
заменил на
ffmpeg -i $FILE -r 30 -s 1280x720 -vcodec libxvid -b 18300k -acodec libmp3lame -ab 192k -ac 2 -ar 48000 ./${fname%MTS}avi

да, так правильней...

"neonii" написал:
/home/user/sortvideo.sh: строка 17: ошибка синтаксиса около неожиданной лексемы `)'
/home/user/sortvideo.sh: строка 17: ` mencoder -ovc copy -oac copy -o "$TARGET/$DIR.avi" $TARGET/$DIR/*.avi)'

скобка в конце не нужная, видно же, что очепятался...

"neonii" написал:
date -d "$(stat -c=%z 1.c)" "+%Y-%m-%d"
тоже пока непонятно

DIR=$(date -d "$(stat -c=%z "$FILE")" "+%Y-%m-%d") ;

#259159

это нашел

"Fat-Zer" написал:
скобка в конце не нужная, видно же, что очепятался...

не успел отписать

вставил в скрипт

text
 DIR=$(date -d "$(stat -c=%z "$FILE")" "+%Y-%m-%d") ; 

скрипт

text

#!/bin/bash

SOURCE=/home/user/tmp/video # исходная папка TARGET=/home/user/video # папка для копирования

find $SOURCE -iname "*.MTS" | while read FILE ; do DIR=$(date -d "$(stat -c=%z "$FILE")" "+%Y-%m-%d") ; mkdir -p $TARGET/$DIR ;

fname="${DIR}-$(basename $FILE)" ffmpeg -i $FILE -r 30 -s 1280x720 -vcodec libxvid -b 18300k -acodec libmp3lame -ab 192k -ac 2 -ar 48000 ./${fname%MTS}avi cp -uv --preserve ./${fname%MTS}avi $TARGET/$DIR; done

теперь дату не подставляет
соответственно папки не создаются. файлы получаются -00000.avi

вернул пока назад как было.

вставляю второй цикл (склейка)
скрипт

text

#!/bin/bash

SOURCE=/home/user/tmp/video # исходная папка TARGET=/home/user/video # папка для копирования

find $SOURCE -iname "*.MTS" | while read FILE ; do DIR=$(ls -l "$FILE" | awk '{print $7"-"$6"-"$8}') ; #DIR=$(date -d "$(stat -c=%z "$FILE")" "+%Y-%m-%d") ; mkdir -p $TARGET/$DIR ;

fname="${DIR}-$(basename $FILE)" ffmpeg -i $FILE -r 30 -s 1280x720 -vcodec libxvid -b 18300k -acodec libmp3lame -ab 192k -ac 2 -ar 48000 ./${fname%MTS}avi cp -uv --preserve ./${fname%MTS}avi $TARGET/$DIR; done find "$TARGET" -maxdepth 1 | while read DIR ; do mencoder -ovc copy -oac copy -o "$TARGET/$DIR.avi" $TARGET/$DIR/*.avi done

результат выполнения 2-го цикла mencoder(ом)

text

Exiting...
MEncoder SVN-r34707-4.6.1 (C) 2000-2012 MPlayer Team
File not found: '/home/user/video//home/user/video/17-мая-2011/*.avi'
Failed to open /home/user/video//home/user/video/17-мая-2011/*.avi.
Cannot open file/device.

Exiting...

я так понял с переменной косяк где-то.

#259167
"neonii" написал:
теперь дату не подставляет
соответственно папки не создаются. файлы получаются -00000.avi

равно лишнее было... небыло возможности проверить...
date -d "$(stat -c %z "$FILE")" "+%Y-%m-%d"

"neonii" написал:
я так понял с переменной косяк где-то.

ну да... $TARGET/ в mencoder'е лишнее...

#259249

Fat-Zer благодарю за помощь!

Все заработало.

единственное заменил z на y

"Fat-Zer" написал:
date -d "$(stat -c %z "$FILE")" "+%Y-%m-%d"

стало

text
 date -d "$(stat -c %y "$FILE")" "+%Y-%m-%d" 

, а то сегодняшним днем дату пробивало (может при копировании меняется, хотя в начале вроде нормально было, потом косяк вылез - покурил man stat, внес изменение, но так и не понял где собака порылась).

Еще сделал вместо копирования перенос, чтоб не засорять и удаление временных файлов и директорий используемых для обработки.

Проверил на нескольких файлах с разной датой. Пока вроде все корректно.
Закинул скрипт в cron.
Настроил на ежедневное выполнение в 01:00 пусть ночью крутится.

За автоматическое монтирование по udev и копирование с SD у меня другой скрипт отвечает.
Теперь лафа. Карточку вставил. Фото и видео слилось beep(нуло 3 раза) чтоб вынут после umount.
Затем фотки по папкам с датами распихались на том и остались (юзал exiftool), а видео обрабатывается этим скриптом.

конечный вариант скрипта

text

#!/bin/bash

SOURCE=/home/user/tmp/video # исходная папка сюда сливается *.MTS с SD карты TARGET=/home/user/tmp/videoavi # папка для преобразованных MTS в avi (тоже временная) потом чистится

# начало первого цикла ищем файлы MTS возвращаем даты модификации, создаем директории имя - дата жмем в avi find $SOURCE -iname "*.MTS" | while read FILE ; do DIR=$(date -d "$(stat -c%y "$FILE")" "+%Y-%m-%d") ; mkdir -p $TARGET/$DIR ; #создаем каталог fname="${DIR}-$(basename $FILE)" ffmpeg -i $FILE -r 30 -s 1280x720 -vcodec libxvid -b 18300k -acodec libmp3lame -ab 192k -ac 2 -ar 48000 ./${fname%MTS}avi mv ./${fname%MTS}avi $TARGET/$DIR; done #второй цикл ищем только-что преобразованные avi уже распиханные в директории по датам и сцепляем в один файл, называем файл по дате. find "$TARGET" -maxdepth 1 | while read DIR ; do mencoder -ovc copy -oac copy -o "/$DIR.avi" $DIR/*.avi mv "$DIR.avi" /home/user/video; # папка должна существовать! done # почистим rm -rf /home/user/tmp/videoavi/* rm -rf /home/user/tmp/video/*

Еще раз спасибо! По моему не плохо получилось )

Войдите или зарегистрируйтесь, чтобы ответить.