Menu
FFmpeg в примерах

FFmpeg в примерах

Простые операции

Извлечение mp3 из mp4:

# ffmpeg -i antistress.mp4 -vn  -acodec libmp3lame -ac 2 -ab 160k -ar 44100 antistress.mp3

Преобразование H264 в mp4:

# ffmpeg -framerate 24 -i 08.55.16-08.55.29[M][@e50][0].h264 -c copy output.mp4

Преобразование чего-то в mp4 h264 для публикаций в web

# ffmpeg -i input.flv -vcodec libx264 -acodec aac output.mp4 

Склейка

# ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4

где list  file '1.mp4'   file '2.mp4'

Обрезка области (Crop area)

-vf "crop=w:h:x:y" 

, где w - длина прямоугольника, h - высота прямоугольника, x и y - координата левого верхнего угла отступая с левого верхнего угла оригинального изображения

Так в данном случае "-c:v copy " не будет работать. Нужно указать кодек явно

Например, запись части экрана с камеры axis:

# ffmpeg -re -rtsp_transport tcp -i "rtsp://login:pass@camera-ip/axis-media/media.amp?resolution=1920x1080&audiochannel=1&audio=1&videocodec=h264" -t 01:00:00 -c:a copy -vf "crop=854:480:850:330" -crf 23 -f flv -vcodec libx264     "$(date +%y%m%d-%H%M%S).mp4"

Сохранить поток продолжительностью 1 час в файл 

# ffmpeg -t 01:00:00 -i "http://stream.myradio.com:8000" -ar 44100 -ac 2 -ab 80K -f mp3 "/archive/$(date +%Y-%m-%d+%H).mp3"

Прописать в cron 0 * * * * root /root/recording.sh

# nohup /usr/bin/ffmpeg -t 01:00:00 -i "http://stream.myradio.com:8000" -ar 44100 -ac 2 -ab 80K -f mp3 "/archive/$(date +%Y-%m-%d+%H).mp3" > >/dev/null 2>&1 &

Совместить видео, аудио потоки и картинку и записать в файл

# ffmpeg -i rtsp://domain.com/video.pro1 \

-i http://stream.myradio.com:8000/ \

-vf "movie=icon.png [watermark]; [in][watermark] overlay=10:10 [out]" \

-map 0:v:0 -map 1:a:0 \

-c:v libvpx-vp9 \

-c:a libvorbis \

-s 1024x768 -t 01:00:00 $(date +%y%m%d-%H%M%S).webm

Выложить на сайт

<video controls 

  <source src="output.mp4"      type="video/mp4">

  <source src="output.webm" type="video/webm">

    poster="poster.jpg"

    width="620" />

Собрать много JPG в видео

Скрипт

#!/bin/bash

JPGSGR=""

j=0 ; for f in *.jpg ;

do

 if [ "${f:0:14}" !=  "$JPGSGR" ]

 then

  JPGSGR="${f:0:14}"

  echo "$JPGSGR"

  cp $JPGSGR*.jpg ./mov/

  cd ./mov

  i=0 ; for f in *.jpg ; do mv "$f" $(printf "$JPGSGR%04d.jpg" $i) ; i=$((i+1)) ; done

  ffmpeg -r 2 -y -i "$JPGSGR%04d.jpg"  -vcodec flv $JPGSGR.flv

  rm *.jpg

  cd ..

 fi

done

Сохранить каждые 5 секунд из RTSP потока

ffmpeg -rtsp_flags listen -rtsp_transport udp -stimeout 1000000 -i rtsp://127.0.0.1:31415/live.stream -vf scale="-1:72" -r 0.05 -vsync 2 img_%05d.jpg

HLS

C изменением размера и указанием кодека

# ffmpeg -i rtsp://camera-ip/video.pro1 \

-i http://stream.myradio.com:8000/ \

-vf "movie=icon.png [watermark]; [in][watermark] overlay=10:10 [out]" \

-map 0:v:0 -map 1:a:0 \

-c:v libx264 -crf 21 -preset veryfast \

-c:a aac -b:a 64k -ac 2 \

-hls_flags delete_segments \

-hls_segment_filename /usr/local/nginx/html/segment-%03d.ts \

/usr/local/nginx/html/live.m3u8

Оригинальный размер и кодек (не жрет процессор)

( но лого не наложить - это перекодировка)

# ffmpeg -i rtsp://camera-ip/video.pro1 \

-i http://stream.myradio.com:8000/ \

-c:v copy -crf 21 -preset veryfast \

-c:a copy -b:a 64k -ac 2 \

-hls_time 25 \

-hls_flags delete_segments \

-hls_segment_filename /usr/local/nginx/html/segment-%03d.ts \

/usr/local/nginx/html/live.m3u8

C указанием размера с камеры 

ffmpeg -re -rtsp_transport tcp -i "rtsp://camera-ip/video.pro1" \

    -hls_time 25 \

    -hls_flags delete_segments \

    -hls_segment_filename /tmp/segm/segment-%03d.ts \

    /tmp/segm/live.m3u8

   

Публикация на сайте

<script src="hls.js"></script> <video id="video" controls style="width: 800px;"></video> <script> if(Hls.isSupported()) { var video = document.getElementById('video'); var hls = new Hls(); hls.loadSource('live.m3u8'); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED,function() { video.play(); }); } else if (video.canPlayType('application/vnd.apple.mpegurl')) { video.src = 'playlist.m3u8'; video.addEventListener('canplay',function() { video.play(); }); } </script>   Старт HTML5 audio/video с определенной позиции

 Трансляция HLS в Youtube

ffmpeg -re -i "/tmp/segm/live.m3u8" -vcodec libx264 -preset "ultrafast" -maxrate 3000k -b:v 2500k -bufsize 600k -pix_fmt yuv420p -g 60 -c:a aac -b:a 160k -ac 2 -ar 44100 -f flv -s 1280x720 "rtmp://a.rtmp.youtube.com/{event}/{key}"

Трансляция потока с камеры в Видеохостинги

Сейчас в основном используется соотношение сторон 16:9 со следующими разрешениями:

  • 2160p: 3840 x 2160
  • 1440p: 2560 x 1440
  • 1080p: 1920 x 1080
  • 720p: 1280 x 720
  • 480p: 854 x 480
  • 360p: 640 x 360
  • 240p: 426 x 240

Youtube

Просто трансляция файла 

# ffmpeg -re -i mystream.mp4 -f flv "rtmp://a.rtmp.youtube.com/live2/KEY"

Трансляция с камеры axis по запланированному заданию продолжительностью 1 час с максимальным разрешением и сохранением качества

# ffmpeg -re -rtsp_transport tcp -i "rtsp://user:pass@camera-ip/axis-media/media.amp?resolution=1920x1080&audiochannel=1&audio=1&videocodec=h264" -t 01:01:00 -c:v copy -c:a copy -flvflags  --o_duration_filesize -f flv   "rtmp://a.rtmp.youtube.com/live2/KEY"

При возникновении ошибки Failed to update header...

[flv @ 0x55ad4fad0880] Failed to update header with correct duration.

[flv @ 0x55ad4fad0880] Failed to update header with correct filesize.

ffmpeg пытается записать заголовок в файл, но так как это стрим, то не может. Надо добавить флаг

-flvflags no_duration_filesize

Встраивание трансляции Youtube с постоянной ссылкой

- получить идентификатор канала тут https://www.youtube.com/account_advanced

Ссылка http://youtube.com/channel/CHANNEL_ID/live

Встраивание 

<iframe width="560" height="315" src="https://www.youtube.com/embed/live_stream?channel=CHANNELID" frameborder="0" allowfullscreen></iframe>

Вконтакте

Создание:

vk.com -> Видео -> Добавить -> Начать трансляцию

# ffmpeg -re -rtsp_transport tcp -i "rtsp://user:pass@camera-ip/axis-media/media.amp?resolution=1920x1080&audiochannel=1&audio=1&videocodec=h264" -t 01:01:00 -c:v copy -c:a copy -flvflags  --o_duration_filesize -f flv "rtmp://ovsu.mycdn.me/input/KEY"

  • после обновления ffmpeg функция no_duration_filesize стала недоступна.

Преобразование аудио в текст (vosk)

Не ffmpeg, но может быть полезно

Установка

sudo apt update
sudo apt install -y python3 python3-pip ffmpeg unzip rename
sudo pip3 install vosk
Скачать языковые модели
wget https://alphacephei.com/vosk/models/vosk-model-ru-0.22.zip
unzip vosk-model-ru-0.22.zip

Использование

vosk-transcriber -i file.mp3 -o file.txt -m /path/to/model/

Скрипт пакетной обработки - можно запихнуть в cron

#!/bin/bash

MP3DIR="/home/mp3-to-txt"
MODEL="/home/models/vosk-model-small-ru-0.22/"
#MODEL="vosk-model-ru-0.42/"
if [ ! -f "$MP3DIR/.busy" ]; then
  touch "$MP3DIR/.busy"
  for file in $MP3DIR/*.mp3;
  do
      #wc -l $file;
      #stat -c %s $file;
      name=${file%.*}
      if [ ! -f "$name.txt" ]; then
          vosk-transcriber -i $file -o $name.txt -m $MODEL
      fi
  done
  rm $MP3DIR/.busy
fi


... продолжение следует

Lisolog (2022)