Задача: Автоматически конвертировать видео для стримминга через nginx
Допустим у нас на сервере есть папка куда будет поступать видео файлы, обычные которые вы скачиваете через торрент. Нам необходимо автоматически конвертировать эти файлы для пригодного формата.
Теперь приступим. На сервере должна быть установлена ffmpeg с H264 енкодером. В этом вам поможет гугл.
Есть замечательный инструмент ffprobe, который может извлекать всю необходимую информацию из медиа файла, и выводить в красивом(json, xml) формате. Нам надо пройтись по папке и найти все видео файлы, и записать в json файл.
Вот скрипт:
В конце у нас получится готовый bash скрипт для запуска.
Теперь соединим все в один файл:
P.S. код на гитхабе https://github.com/samlabs821/Server-side/
Допустим у нас на сервере есть папка куда будет поступать видео файлы, обычные которые вы скачиваете через торрент. Нам необходимо автоматически конвертировать эти файлы для пригодного формата.
Теперь приступим. На сервере должна быть установлена ffmpeg с H264 енкодером. В этом вам поможет гугл.
Есть замечательный инструмент ffprobe, который может извлекать всю необходимую информацию из медиа файла, и выводить в красивом(json, xml) формате. Нам надо пройтись по папке и найти все видео файлы, и записать в json файл.
#!/bin/bash
INPUT_DIR="/home/user1/to_convert/"
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
rm videofiles.json
count=$(find $INPUT_DIR -name "*.avi" | wc -l)
echo "[" >> 'videofiles.json'
for i in $(find $INPUT_DIR -name "*.avi")
do
ffprobe -v quiet -print_format json -show_format $i >> 'videofiles.json'
if [ $count -ne 1 ];then
echo "," >> 'videofiles.json'
count=$(( $count - 1 ))
echo $count
fi
done;
echo "]" >> 'videofiles.json'
IFS=$SAVEIFS
Следующий шаг, сделать готовый bash скрипт из json файла. 2-й этап возьмет на себя питон скрипт. Почему питон? Потому что есть готовый парсер для json, да и времени сэкономит.Вот скрипт:
#!/usr/bin/python
import json
import os
import sys
import codecs
def ffmpegReady(filename, destFile1, destFile2, bit_rate):
bitrate=int(bit_rate)
bitrate1=0
bitrate2=0
if 1500 < bitrate:
bitrate1=str(int(bitrate*0.8))
bitrate2=str(int(bitrate*0.25))
elif bitrate <1500:
bitrate1=str(int(bitrate*0.9))
bitrate2=str(int(bitrate*0.33))
ffmpeg_command = "ffmpeg -i \""+filename +"\" -vcodec libx264 -acodec libfaac -b:v "+bitrate1+"k -threads 0 -r 24 -g 24 \""+destFile1+".mp4"+"\"\n"
ffmpeg_command = ffmpeg_command + "qtfaststart \""+destFile1+".mp4\" \""+destFile1[:-4]+".mp4\"\n"
ffmpeg_command = ffmpeg_command + "rm -f \""+ destFile1+".mp4\"\n"
ffmpeg_command = ffmpeg_command + "ffmpeg -i \""+filename +"\" -s 480x360 -vcodec libx264 -acodec libfaac -b:v "+bitrate2+"k -threads 0 -r 24 -g 24 \""+destFile2+".mp4"+"\"\n"
ffmpeg_command = ffmpeg_command + "qtfaststart \""+destFile2+".mp4\" \""+destFile2[:-4]+".mp4\"\n"
ffmpeg_command = ffmpeg_command + "rm -f \"" + destFile2 + ".mp4\"\n"
ffmpeg_command = ffmpeg_command + "rm -f \""+ filename+"\"\n"
return ffmpeg_command
здесь я показал часть которая генерирует команду. Как видите у меня 2 выходных файла. Один с нормальным, другой с низким качеством. Также используется утилита qtfaststart для перемещения мета информации в начало файла. Это поможет нам уменьшить время запуска проигрывания.В конце у нас получится готовый bash скрипт для запуска.
Теперь соединим все в один файл:
#!/bin/bash
DATE=`/bin/date`
qt=$(ps aux | grep 'qtfaststart' | grep -v grep | wc -l | tr -s "\n")
ff_p=$(ps aux | grep 'ffmpeg' | grep -v grep | wc -l | tr -s "\n")
if [ -e convert_process ]
then
echo "$DATE process not finished" >> log.txt
else
if [[ $qt > 0 || $ff_p > 0 ]]
then
echo "ffmpeg or qtfaststart already running, try later" >> log.txt
else
touch convert_process
echo "$DATE Scanning ..." >> log.txt
./convert.sh
echo "$DATE Parsing ..." >> log.txt
./parsejson.py
echo "$DATE Starting ..." >> log.txt
screen -d -m ./runnable.sh
echo "$DATE Finished." >> log.txt
rm -f convert_process
fi
fi
Все. Скрипт можно поставить в крон задачи. Статья не претендует на how to. Это просто один из тысячи методов. Также приветсвуется подсказки и пожелания.