LINUX.ORG.RU

ffmpeg прерывает цикл в скрипте

 , ,


2

2

Добрый день!
Есть список клипов которые нужно выкачать частично, с указанием начала (вторая колонка) и конца (третья колонка) и имя, под которым он сохраняется (четвертая колонка).

url1 00:14:00 00:15:00 name1
url2 00:09:00 00:10:10 name2
url3 00:14:00 00:15:00 name3
url4 00:09:00 00:10:20 name4

и есть скриптик, при помощи которого нужно это дело скачать.
#!/bin/bash
cat ./list | while read line; do
url=$(echo $line | awk '{print $1}');
start=$(echo $line | awk '{print $2}');
end=$(echo $line | awk '{print $3}');
name=$(echo $line | awk '{print $4}');
clip=$(echo "ffmpeg -ss "$start" -to "$end" -i "\$\(youtube-dl -g \"$url\"\)" -c copy ./"\""$name"\"".mp4");
bash -c "$clip"
done;
После запуска скачивается только первый клип и цикл заканчивается.
Как продолжить выполнение скрипта?
Подскажите, где я накосячил?
Спасибо!


На вид должно работать(хоть и написано ужасно :) ).

Покажи вывод bash -x script.sh

Посмотрим, что оно у тебя пытается сделать.

shell-script ★★★★★
()

awk '{print $1}'

cut -f1 -d" "

clip=$(echo "...") зачем? Просто выполни команду с подстановкой переменных.

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

cut -f1 -d" "

$ cat /tmp/zz
url1 00:14:00 00:15:00 name1
url2 00:09:00 00:10:10 name2
url3 00:14:00 00:15:00 name3
url4 00:09:00 00:10:20 name4

$ while read url start end name; do echo "$name - $start - $end - $url"; done < /tmp/zz
name1 - 00:14:00 - 00:15:00 - url1
name2 - 00:09:00 - 00:10:10 - url2
name3 - 00:14:00 - 00:15:00 - url3
name4 - 00:09:00 - 00:10:20 - url4
joy4eg ★★★★★
()
clip=$(echo "ffmpeg -ss "$start" -to "$end" -i "\$\(youtube-dl -g \"$url\"\)" -c copy ./"\""$name"\"".mp4");
bash -c "$clip"


что за херня?

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

Не знаю, скорее всего да.
По крайней мере ты перейдёшь к прямму запуску ffmpeg исключив возможные ошибки связанные с его запуском через bash и вообще упростишь скрипт.

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

Имхо, ТС всё правильно делает, с точки зрения разработки вообще (не с точки зрения починки бага из оп-поста)

Это очень правильная архитектура - разбить скрипт на смысловые блоки, хорошо внутри организовать архитектуру, итп

Если мешать всё в одно говно, через некоторое время вместо скриптов будет нечитабельная каша, поддерживать которую без поллитры невозможно

stevejobs ★★★★☆
()

Поменяй clip=$(...) на clip="echo $name" и увидишь, что у тебя выводится только одна строка.

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

Как раз на оборот, ТС написал много лишнего, а joy4eg использует возможности команды read получив за счёт этого значительное упрощение скрипта.

То есть все строки вида url=$(echo $line | awk ‘{print $1}’); не нужны, команда read делает всё тоже самое причём сразу для всех переменных.

torvn77 ★★★★★
()
Последнее исправление: torvn77 (всего исправлений: 1)
Ответ на: комментарий от torvn77

У тебя должно быть несколько уровней абстракции

Один уровень - чтение параметров на входе и перекладывание их в локальные переменные с понятными именами

Второй уровень - это всякая логика, вычисление чего-то (например, путей на файлухе), и перекладывание их в локальные переменные

Дальше идёт конструирование шаблона

И вот под самый конец уже идёт команда на выполнение

Это примерно та же штука, как когда ты пишешь веб-страницу. Никто не вписывает переменные прямо в веб-страницу, кроме совсем кондовых похапэшников. У тебя есть паттерн Model-View-Controller. Вначале ты читаешь данные из базы, потом перекладываешь в Data Transfer Objects, потом считаешь что-то в контроллере, потом наполняешь DTO-шками модель, потом моделью подменяешь плейсхолдеры в шаблоне веб-страницы, и только потом уже показываешь это всё на экране. А если у тебя там JS-вебморда, то всё это происходит по второму разу в браузере, только вместо базы там будет JSON API сайта. А тут у тебя вместо базы - текстовый файл.

На самом деле, я бы понаписал туда еще несколько блоков ;)

stevejobs ★★★★☆
()
Ответ на: комментарий от serles

Тогда может сервер банит? Попробуй на локальных файлах.

anonymous
()
Ответ на: cat ./list | while read -u7 line; do от serles
#!/bin/bash
exec 7<./list
while read -u7 line; do
  url=$(echo $line | awk '{print $1}');
  start=$(echo $line | awk '{print $2}');
  end=$(echo $line | awk '{print $3}');
  name=$(echo $line | awk '{print $4}');
  clip=$(echo "ffmpeg -ss "$start" -to "$end" -i "\$\(youtube-dl -g \"$url\"\)" -c copy ./"\""$name"\"".mp4");
  bash -c "$clip"
done;
anonymous
()
Ответ на: комментарий от anonymous

Еще раз спасибо огромное за помощь!

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

Предположу, что дело в том, что ffmpeg зачем-то читает stdin, поэтому после первой итерации read было уже нечего читать.
Однако тоже интересно, почему тогда не сработало < /dev/null, и ключ -nostdin?

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

кстати да. есть такая тема про чтение ffmpeg'ом stdin. надо ему специальный ключ указывать чтоб не читал

teod0r ★★★★★
()

Тебе дали правильный ответ ffmpeg прерывает цикл в скрипте (комментарий) и ffmpeg прерывает цикл в скрипте (комментарий)

ты просто не осилил его применить. exec 7<./list ... read -u7 работает ровно по той-же причина, по которой сработал бы ffmpeg …. < /dev/null - ffmpeg съедает данные из stdin и read голодает.

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

Однако тоже интересно, почему тогда не сработало < /dev/null, и ключ -nostdin?

Потому, что анон с exec расжевал и ротик положил готовый скрипт (ужасный совершенно, все эти var=(echo | awk) содомические до омерзения).

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