Repository: Eyevinn/toolbox Branch: master Commit: ef13bda3fdb1 Files: 45 Total size: 42.1 KB Directory structure: gitextract_4l0c7964/ ├── .gitignore ├── Dockerfile.bento4 ├── Dockerfile.ffmpeg ├── Dockerfile.ffmpeg-mp3 ├── Dockerfile.gpac ├── Dockerfile.gst ├── Dockerfile.hls2rtmp ├── Dockerfile.hls2srt ├── Dockerfile.hls2ts ├── Dockerfile.loopts ├── Dockerfile.mosaicts ├── Dockerfile.rtmp2srt ├── Dockerfile.rtmprx ├── Dockerfile.srt2rtmp ├── Dockerfile.srtrx ├── Dockerfile.srttx ├── Dockerfile.transcode ├── LICENSE ├── README.md ├── build-bento4.sh ├── build-ffmpeg.sh ├── build-gpac.sh ├── build-gst.sh ├── build-hls2rtmp.sh ├── build-hls2srt.sh ├── build-hls2ts.sh ├── build-loopts.sh ├── build-mosaicts.sh ├── build-rtmp2srt.sh ├── build-rtmprx.sh ├── build-srt2rtmp.sh ├── build-srtrx.sh ├── build-srttx.sh ├── build-transcode.sh └── python/ ├── hls2rtmp.py ├── hls2srt.py ├── hls2ts.py ├── loopts.py ├── mosaicts.py ├── rtmp2srt.py ├── rtmprx.py ├── srt2rtmp.py ├── srtrx.py ├── srttx.py └── transcode.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ test/ ================================================ FILE: Dockerfile.bento4 ================================================ FROM eyevinntechnology/ffmpeg-base:0.3.0 RUN apt-get install -y unzip RUN cd /root/source && \ wget http://zebulon.bok.net/Bento4/binaries/Bento4-SDK-1-6-0-634.x86_64-unknown-linux.zip && \ unzip ./Bento4-SDK-1-6-0-634.x86_64-unknown-linux.zip -d /usr/local && \ ln -s /usr/local/Bento4-SDK-1-6-0-634.x86_64-unknown-linux /usr/local/bento4 ENV PATH="${PATH}:/usr/local/bento4/bin" ================================================ FILE: Dockerfile.ffmpeg ================================================ FROM ubuntu:22.04 LABEL MAINTAINER="Eyevinn Technology " ARG DEBIAN_FRONTEND=noninteractive RUN apt-get -y update RUN apt-get install -y autoconf RUN apt-get install -y --force-yes automake RUN apt-get install -y --force-yes build-essential RUN apt-get install -y --force-yes pkg-config RUN apt-get install -y --force-yes libtool RUN apt-get install -y --force-yes wget RUN apt-get install -y --force-yes yasm RUN apt-get install -y --force-yes libx264-dev RUN mkdir /root/source RUN mkdir /root/source/ffmpeg RUN cd /root/source/ffmpeg && \ wget -O fdk-aac.tar.gz https://github.com/mstorsjo/fdk-aac/tarball/master && \ tar xzvf fdk-aac.tar.gz && \ cd mstorsjo-fdk-aac* && \ autoreconf -fiv && \ ./configure --disable-shared && \ make && \ make install && \ make distclean RUN apt-get install -y --force-yes git RUN apt-get install -y --force-yes cmake RUN apt-get install -y --force-yes python2.7 RUN mkdir -p /root/source/ffmpeg/libaom && \ cd /root/source/ffmpeg/libaom && \ git clone https://aomedia.googlesource.com/aom && \ cmake ./aom && \ make && \ make install RUN apt-get install -y --force-yes python3 python3-pip ninja-build RUN pip3 install meson RUN apt-get install -y --force-yes nasm RUN cd /root/source/ffmpeg && \ git clone https://code.videolan.org/videolan/dav1d.git && \ cd dav1d && \ meson build --buildtype release && \ ninja -C build && \ ninja -C build install && \ ldconfig RUN apt-get install -y --force-yes libvpx-dev RUN apt-get install -y --force-yes libssl-dev RUN apt-get install -y --force-yes tclsh RUN cd /root/source/ffmpeg && \ git clone https://github.com/Haivision/srt.git && \ cd srt && \ ./configure && \ make && make install && \ ldconfig RUN apt-get install -y --force-yes libx265-dev libnuma-dev RUN apt-get install -y --force-yes libfreetype6-dev RUN apt-get install -y --force-yes libopus-dev RUN apt-get install -y --force-yes openssl RUN apt-get install -y --force-yes libssl-dev RUN apt-get install -y --force-yes libmp3lame-dev RUN cd /root/source/ffmpeg && \ wget http://ffmpeg.org/releases/ffmpeg-6.0.tar.bz2 && \ tar xjvf ffmpeg-6.0.tar.bz2 && \ cd ffmpeg-6.0 && \ ./configure \ --pkg-config-flags="--static" \ --enable-gpl \ --enable-libfdk-aac \ --enable-libx264 \ --enable-libaom \ --enable-libdav1d \ --enable-libvpx \ --enable-libsrt \ --enable-libx265 \ --enable-libfreetype \ --enable-libopus \ --enable-libmp3lame \ --enable-version3 \ --enable-openssl \ --enable-nonfree && \ make && \ make install && \ make distclean && \ hash -r ================================================ FILE: Dockerfile.ffmpeg-mp3 ================================================ FROM eyevinntechnology/ffmpeg-base:0.3.0 RUN apt-get install -y libmp3lame-dev RUN cd /root/source/ffmpeg && \ cd ffmpeg && \ ./configure \ --pkg-config-flags="--static" \ --enable-gpl \ --enable-libfdk-aac \ --enable-libx264 \ --enable-libaom \ --enable-libdav1d \ --enable-libvpx \ --enable-libsrt \ --enable-libx265 \ --enable-libfreetype \ --enable-libopus \ --enable-libmp3lame \ --enable-version3 \ --enable-openssl \ --enable-nonfree && \ make && \ make install && \ make distclean && \ hash -r ================================================ FILE: Dockerfile.gpac ================================================ FROM ubuntu:14.04 MAINTAINER Eyevinn Technology RUN apt-get update RUN apt-get install -y --force-yes subversion make pkg-config \ g++ zlib1g-dev libfreetype6-dev libjpeg62-dev libpng12-dev \ libopenjpeg-dev libmad0-dev libfaad-dev libogg-dev libvorbis-dev \ libtheora-dev liba52-0.7.4-dev libavcodec-dev libavformat-dev \ libavutil-dev libswscale-dev libavresample-dev libxv-dev x11proto-video-dev \ libgl1-mesa-dev x11proto-gl-dev linux-sound-base libxvidcore-dev libssl-dev \ libjack-dev libasound2-dev libpulse-dev libsdl1.2-dev dvb-apps libavcodec-extra \ libavdevice-dev libmozjs185-dev RUN apt-get install -y --force-yes git RUN mkdir /root/source RUN apt-get install -y --force-yes libx264-dev RUN apt-get install -y --force-yes yasm RUN apt-get install -y --force-yes wget RUN mkdir /root/source/ffmpeg RUN apt-get install -y --force-yes libssl-dev RUN apt-get install -y --force-yes cmake RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --force-yes tclsh RUN cd /root/source/ffmpeg && \ git clone https://github.com/Haivision/srt.git && \ cd srt && \ ./configure && \ make && make install && \ ldconfig RUN cd /root/source/ffmpeg && \ wget http://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2 && \ tar xjvf ffmpeg-snapshot.tar.bz2 && \ cd ffmpeg && \ ./configure \ --enable-gpl \ --enable-shared \ --enable-libx264 \ --enable-libsrt \ --enable-version3 \ --enable-nonfree && \ make && \ make install && \ make distclean && \ hash -r RUN cd /root/source/ && \ git clone https://github.com/gpac/gpac.git && \ cd gpac && \ ./configure && \ make && \ make install && \ hash -r RUN echo /usr/local/lib/x86_64-linux-gnu >> /etc/ld.so.conf.d/x86_64-linux-gnu.conf RUN ldconfig ================================================ FILE: Dockerfile.gst ================================================ FROM eyevinntechnology/ffmpeg-base:0.1.3 MAINTAINER Eyevinn Technology RUN apt-get update RUN apt-get install -y --force-yes libgstreamer1.0-0 gstreamer1.0-plugins-base \ gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \ gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools gstreamer1.0-x \ gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 \ gstreamer1.0-pulseaudio ================================================ FILE: Dockerfile.hls2rtmp ================================================ FROM eyevinntechnology/ffmpeg-base:0.3.0 MAINTAINER Eyevinn Technology COPY python/hls2rtmp.py /root/hls2rtmp.py ENTRYPOINT ["/root/hls2rtmp.py"] CMD [] ================================================ FILE: Dockerfile.hls2srt ================================================ FROM eyevinntechnology/ffmpeg-base:0.3.0 MAINTAINER Eyevinn Technology COPY python/hls2srt.py /root/hls2srt.py ENTRYPOINT ["/root/hls2srt.py"] CMD [] ================================================ FILE: Dockerfile.hls2ts ================================================ FROM eyevinntechnology/ffmpeg-base:0.2.2 MAINTAINER Eyevinn Technology COPY python/hls2ts.py /root/hls2ts.py ENTRYPOINT ["/root/hls2ts.py"] CMD [] ================================================ FILE: Dockerfile.loopts ================================================ FROM eyevinntechnology/ffmpeg-base:0.1.3 MAINTAINER Eyevinn Technology COPY fonts/Vera.ttf /root/Vera.ttf COPY python/loopts.py /root/loopts.py ENTRYPOINT ["/root/loopts.py"] CMD [] ================================================ FILE: Dockerfile.mosaicts ================================================ FROM eyevinntechnology/ffmpeg-base:0.1.3 MAINTAINER Eyevinn Technology COPY python/mosaicts.py /root/mosaicts.py ENTRYPOINT ["/root/mosaicts.py"] CMD [] ================================================ FILE: Dockerfile.rtmp2srt ================================================ FROM eyevinntechnology/ffmpeg-base:0.3.0 MAINTAINER Eyevinn Technology COPY python/rtmp2srt.py /root/rtmp2srt.py ENTRYPOINT ["/root/rtmp2srt.py"] CMD [] ================================================ FILE: Dockerfile.rtmprx ================================================ FROM eyevinntechnology/ffmpeg-base:0.1.3 MAINTAINER Eyevinn Technology COPY python/rtmprx.py /root/rtmprx.py ENTRYPOINT ["/root/rtmprx.py"] CMD [] ================================================ FILE: Dockerfile.srt2rtmp ================================================ FROM eyevinntechnology/ffmpeg-base:0.3.0 MAINTAINER Eyevinn Technology COPY python/srt2rtmp.py /root/srt2rtmp.py ENTRYPOINT ["/root/srt2rtmp.py"] CMD [] ================================================ FILE: Dockerfile.srtrx ================================================ FROM eyevinntechnology/ffmpeg-base:0.1.3 MAINTAINER Eyevinn Technology COPY python/srtrx.py /root/srtrx.py ENTRYPOINT ["/root/srtrx.py"] CMD [] ================================================ FILE: Dockerfile.srttx ================================================ FROM eyevinntechnology/ffmpeg-base:0.3.0 MAINTAINER Eyevinn Technology COPY python/srttx.py /root/srttx.py ENTRYPOINT ["/root/srttx.py"] CMD [] ================================================ FILE: Dockerfile.transcode ================================================ FROM eyevinntechnology/ffmpeg-base:0.3.0 MAINTAINER Eyevinn Technology COPY python/transcode.py /root/transcode.py ENTRYPOINT ["/root/transcode.py"] CMD [] ================================================ FILE: LICENSE ================================================ The scripts used in the containers are licensed under the MIT License: The MIT License Copyright (c) 2019 Eyevinn Technology (eyevinn.github.io) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Eyevinn Toolbox The Eyevinn Toolbox is a set of Docker containers with tools that may come in handy. They are all free to use and if you have any suggestions feel free to create a ticket. | Tool | Description | Container | | ---- | ----------- | --------- | | Loop TS | Generate MPEG-TS stream over multicast or SRT by looping an MP4 file | eyevinntechnology/toolbox-loopts | | SRT Tx | Transport stream over SRT | eyevinntechnology/toolbox-srttx | | SRT Rx | Receive stream over SRT | eyevinntechnology/toolbox-srtrx | | RTMP Rx | Receive RTMP and stream over multicast | eyevinntechnology/toolbox-rtmprx | | Mosaic TS | Render a 2x2 or 3x3 mosaic in MPEG-TS from 4 or 9 HLS sources | eyevinntechnology/toolbox-mosaicts | | HLS 2 TS | Pull a live HLS stream and output to multicast TS | eyevinntechnology/toolbox-hls2ts | | HLS 2 RTMP | Pull a live HLS stream and re-stream to multiple RTMP destinations. | eyevinntechnology/toolbox-hls2rtmp | | HLS 2 SRT | Pull a live HLS stream and transmit over SRT | eyevinntechnology/toolbox-hls2srt | | SRT 2 RTMP | Receive an SRT stream and re-stream to multiple RTMP destinations. | eyevinntechnology/toolbox-srt2rtmp | | RTMP 2 SRT | Receive an RTMP stream and transmit over SRT. | eyevinntechnology/toolbox-rtmp2srt | | VOD Transcode | Quickly transcode video file to a set of different bitrates | eyevinntechnology/toolbox-transcode | ## Loop input file and output MPEG-TS multicast ``` $ docker run --rm -v $PWD:/mnt eyevinntechnology/toolbox-loopts IN.mp4 udp://239.0.0.1.1234?pkt_size=1316 ``` where `$PWD` is your working directory where you have your input file. The following options are available: ``` $ docker run --rm -v $PWD:/mnt eyevinntechnology/toolbox-loopts -h usage: loopts.py [-h] [--workdir WORKDIR] [--framerate FRAMERATE] [--kfinterval KFINTERVAL] [--bitrate BITRATE] [--hevc] [--withtc] [--withaudio] [--nologo] [--useflv] [--multibitrate] inputfile multicast Loop an MP4 file and output to MPEG-TS multicast positional arguments: inputfile multicast optional arguments: -h, --help show this help message and exit --workdir WORKDIR specify a working directory, default is /mnt --framerate FRAMERATE output framerate (DEFAULT 25fps) --kfinterval KFINTERVAL specify keyframe interval (DEFAULT 2 sec) --bitrate BITRATE specify video bitrate in kbps (e.g. 2500) --hevc use HEVC encoded output --withtc burn in local timecode in video output --withaudio adds a test tone on the audio track --nologo remove logo --useflv use FLV for RTMP output --multibitrate output multiple video bitrates ``` To test this locally on your computer (Mac + VLC) assuming the file to loop is called IN.mp4 and in your working directory ``` $ docker run --rm -p 9998:9998/udp -v $PWD:/mnt eyevinntechnology/toolbox-loopts IN.mp4 udp://host.docker.internal:9998?pkt_size=1316 --withtc ``` Then open VLC with the following network address: `udp://@127.0.0.1:9998` ### Output MPEG-TS over SRT To use SRT (Secure Reliable Transport) instead of multicast you can run `loopts` as an SRT listener. ``` docker run --rm -p 9998:9998/udp -v $PWD:/mnt eyevinntechnology/toolbox-loopts IN.mp4 "srt://0.0.0.0:9998?pkt_size=1316&mode=listener" --withtc ``` Then open VLC with the following network address: `srt://@127.0.0.1:9998` ### Output FLV over RTMP To use RTMP instead of multicast you can run `loopts` and push with RTMP ``` docker run --rm -it -v $PWD:/mnt eyevinntechnology/toolbox-loopts --useflv IN.mp4 "rtmp://live.twitch.tv/app/live_*****" ``` ## Receive MPEG-TS over SRT and restream over multicast Use the `srtrx` tool to receive an MPEG-TS stream over SRT (Secure Reliable Transport) and restream over multicast. This can be used in the following scenario: ``` +-----------+ +-----------------+ +------------+ | | | | | | | SRT Tx | ===> INTERNET ===> | toolbox-srtrx | ====> MULTICAST ====> | TRANSCODER | | | | | | | +-----------+ +-----------------+ +------------+ ``` Assuming that the `SRT Tx` is running in listener mode and can be reached on 10.0.110.178:9998 you start the restreamer with the following commmand: ``` $ docker run --rm -p 1234:1234/udp eyevinntechnology/toolbox-srtrx 10.0.110.178:9998 239.0.0.1:1234 ``` This setup can be emulated by running loopts tool as the `SRT Tx` and VLC as the transcoder. ``` $ docker run --rm -p 9998:9998/udp -v $PWD:/mnt eyevinntechnology/toolbox-loopts IN.mp4 "srt://0.0.0.0:9998?pkt_size=1316&mode=listener" --withtc ``` ``` $ docker run --rm -p 9999:9999/udp eyevinntechnology/toolbox-srtrx 10.0.110.178:9998 host.docker.internal:9999 ``` where 10.0.110.178 is the IP of your computer running the loopts container. ``` $ docker run --rm eyevinntechnology/toolbox-srtrx -h usage: srtrx.py [-h] [--listener] [--with-debug] inputaddress outputaddress Receive MPEG-TS over SRT and restream over Multicast positional arguments: inputaddress outputaddress optional arguments: -h, --help show this help message and exit --listener run as SRT listener --passthrough for low latency skip the unmux and mux step. ``` ## Receive RTMP and restream over SRT The `srttx` tool can be used to receive a local RTMP stream and restream to an `SRT Rx` over the Internet. ``` +------------------+ +-----------------+ +------------+ | Wirecast & | | | | | | toolbox-srttx | ===> INTERNET ===> | toolbox-srtrx | ====> MULTICAST ====> | TRANSCODER | | | | | | | +------------------+ +-----------------+ +------------+ ``` On the transmitter side with for example Wirecast as producing the stream first start the `srttx` tool. ``` $ docker run --rm -p 1935:1935 eyevinntechnology/toolbox-srttx:0.2.4 input_stream :9998 --passthrough ``` Then point the Wirecast / OBS output to `rtmp://localhost/live/input_stream` On the receiver side you then run the following: ``` $ docker run --rm -p 9998:9998/udp -p :/udp eyevinntechnology/toolbox-srtrx --listener --passthrough 0.0.0.0:9998 :` ``` ``` $ docker run --rm eyevinntechnology/toolbox-srttx:0.2.4 -h usage: srttx.py [-h] [--inputtype INPUTTYPE] [--listener] [--passthrough] inputstream outputaddress Receive RTMP and stream over SRT positional arguments: inputstream outputaddress optional arguments: -h, --help show this help message and exit --inputtype INPUTTYPE type of input [rtmp|mpegts], default is rtmp --listener run as SRT listener --passthrough passthrough input and skip encoding process ``` ### MPEG-TS as a source The `srttx` tool can also take an MPEG-TS as a source. Instead run the following command on the transmitter side. The receiver side as before. ``` $ docker run --rm eyevinntechnology/toolbox-srttx:0.2.4 : :9998 --passthrough --inputtype=mpegts ``` ## Receive RTMP and restream over Multicast Use the `rtmprx` tool to receive RTMP and restream MPEG-TS over multicast if you want to use RTMP as the transport protocol with a live transcoder that for example only supports MPEG-TS multicast. On the receiver side run the following command: ``` $ docker run --rm -p 1935:1935 -p :/udp eyevinntechnology/toolbox-rtmprx input_stream : --passthrough ``` ``` $ docker run --rm eyevinntechnology/toolbox-rtmprx -h usage: rtmprx.py [-h] [--passthrough] [--with-debug] inputstream outputaddress Receive RTMP and restream over Multicast positional arguments: inputstream outputaddress optional arguments: -h, --help show this help message and exit --passthrough passthrough input and skip encoding process ``` ## Render a Mosaic from HLS sources Use the `mosaicts` tool to render a 2x2 or 3x3 mosaic of HLS sources. ``` $ docker run --rm eyevinntechnology/toolbox-mosaicts -h usage: mosaicts.py [-h] [--port PORT] [--multicast MULTICAST] [--with-debug] layout urlfile Take multiple HLS sources and render a mosaic in MPEG-TS positional arguments: layout 2x2|3x3 urlfile A text file containing URLs to HLS sources. One source per line. optional arguments: -h, --help show this help message and exit --port PORT --multicast MULTICAST Use multicast address specified here instead of SRT ``` To read the list of URLs from STDIN: ``` $ docker run --rm -i -p 9998:9998/udp eyevinntechnology/toolbox-mosaicts 2x2 - < urls.txt ``` ## Pull a live HLS stream and output to multicast TS Use the `hls2ts` tool to pull an HLS live stream and output to multicast TS. ``` $ docker run --rm eyevinntechnology/toolbox-hls2ts -h usage: hls2ts.py [-h] [--srt] [--bitrate BITRATE] [--with-debug] hlsurl outputaddress Pull live HLS and output to multicast TS positional arguments: hlsurl outputaddress optional arguments: -h, --help show this help message and exit --srt use SRT as transport protocol --bitrate BITRATE which bitrate to use --with-debug ``` Example: ``` docker run --rm eyevinntechnology/toolbox-hls2ts:0.1.0 HLSURL : ``` ## Re-stream SRT to multiple RTMP destinations Use the `srt2rtmp` tool to receive an SRT stream and re-stream to multiple RTMP destinations. Example: ``` docker run --rm -p 1234:1234/udp eyevinntechnology/toolbox-srt2rtmp:0.1.1 0.0.0.0:1234 ``` ## Pull a live HLS stream and output to multiple RTMP destinations Use the `hls2rtmp` tool to pull a live HLS stream and re-stream to multiple RTMP destinations. Example: ``` docker run --rm eyevinntechnology/toolbox-hls2rtmp:0.1.3 HLSURL ``` ## Pull a live HLS stream and output to SRT Use the `hls2srt` tool to pull a live HLS stream and make available over SRT. Example: ``` docker run -d --restart always -p 1234:1234/udp eyevinntechnology/toolbox-hls2srt:0.1.1 HLSURL 0.0.0.0:1234 ``` ## Listen for an RTMP stream and output to SRT Use the `rtmp2srt` tool to receive an RTMP stream and transmit over SRT. Example: ``` docker run --rm -p 1935:1935 -p 1234:1234/udp eyevinntechnology/toolbox-rtmp2srt:0.1.1 :1234 ``` By deafult in SRT listener mode, to use SRT as a client: ``` docker run --rm -p 1935:1935 eyevinntechnology/toolbox-rtmp2srt:0.1.0 --caller :1234 ``` ## VOD Transcode Quickly transcode video file to a set of different bitrates. ``` docker run --rm -v $PWD:/media eyevinntechnology/toolbox-transcode:0.1.0 --framerate 24 videofile-720p.mp4 ``` and it will generate three GOP-aligned MP4 files prepared to be chunked into segments. # About Eyevinn Technology Eyevinn Technology is an independent consultant firm specialized in video and streaming. Independent in a way that we are not commercially tied to any platform or technology vendor. At Eyevinn, every software developer consultant has a dedicated budget reserved for open source development and contribution to the open source community. This give us room for innovation, team building and personal competence development. And also gives us as a company a way to contribute back to the open source community. Want to know more about Eyevinn and how it is to work here. Contact us at work@eyevinn.se! ================================================ FILE: build-bento4.sh ================================================ #!/bin/bash docker build -t eyevinntechnology/bento4-base:0.1.0 -f Dockerfile.bento4 . ================================================ FILE: build-ffmpeg.sh ================================================ #!/bin/bash docker build -t eyevinntechnology/ffmpeg-base:0.2.2 -f Dockerfile.ffmpeg . ================================================ FILE: build-gpac.sh ================================================ #!/bin/bash docker build -t eyevinntechnology/gpac-base:0.1.0 -f Dockerfile.gpac . ================================================ FILE: build-gst.sh ================================================ #!/bin/bash docker build -t eyevinntechnology/gst-base:0.1.0 -f Dockerfile.gst . ================================================ FILE: build-hls2rtmp.sh ================================================ #!/bin/bash docker build --no-cache -t eyevinntechnology/toolbox-hls2rtmp:0.1.3 -f Dockerfile.hls2rtmp . ================================================ FILE: build-hls2srt.sh ================================================ #!/bin/bash docker build -t eyevinntechnology/toolbox-hls2srt:0.1.1 -f Dockerfile.hls2srt . ================================================ FILE: build-hls2ts.sh ================================================ #!/bin/bash docker build --no-cache -t eyevinntechnology/toolbox-hls2ts:0.1.3 -f Dockerfile.hls2ts . ================================================ FILE: build-loopts.sh ================================================ #!/bin/bash docker build --no-cache -t eyevinntechnology/toolbox-loopts:0.2.1 -f Dockerfile.loopts . ================================================ FILE: build-mosaicts.sh ================================================ #!/bin/bash docker build --no-cache -t eyevinntechnology/toolbox-mosaicts:0.1.0 -f Dockerfile.mosaicts . ================================================ FILE: build-rtmp2srt.sh ================================================ #!/bin/bash docker build -t eyevinntechnology/toolbox-rtmp2srt:0.1.1 -f Dockerfile.rtmp2srt . ================================================ FILE: build-rtmprx.sh ================================================ #!/bin/bash docker build --no-cache -t eyevinntechnology/toolbox-rtmprx:0.1.0 -f Dockerfile.rtmprx . ================================================ FILE: build-srt2rtmp.sh ================================================ #!/bin/bash docker build --no-cache -t eyevinntechnology/toolbox-srt2rtmp:0.1.1 -f Dockerfile.srt2rtmp . ================================================ FILE: build-srtrx.sh ================================================ #!/bin/bash docker build --no-cache -t eyevinntechnology/toolbox-srtrx:0.1.2 -f Dockerfile.srtrx . ================================================ FILE: build-srttx.sh ================================================ #!/bin/bash docker build -t eyevinntechnology/toolbox-srttx:0.2.4 -f Dockerfile.srttx . ================================================ FILE: build-transcode.sh ================================================ #!/bin/bash docker build -t eyevinntechnology/toolbox-transcode:0.1.0 -f Dockerfile.transcode . ================================================ FILE: python/hls2rtmp.py ================================================ #!/usr/bin/python2.7 # # Copyright 2019 Eyevinn Technology. All rights reserved # Use of this source code is governed by a MIT License # that can be found in the LICENSE file. # Author: Jonas Rydholm Birme (Eyevinn Technology) # # Receive HLS and restream to multiple RTMP destinations # import argparse import subprocess from os.path import basename import re import glob parser = argparse.ArgumentParser(description='Pull HLS and restream to multiple RTMP destinations.') parser.add_argument('hlsurl') parser.add_argument('output', nargs="+") parser.add_argument('--with-programreturn', dest='programreturn', action='store_true', help='open up an SRT program return') parser.add_argument('--returnport', dest='returnport', help='port for the SRT program return') parser.add_argument('--srtmode', dest='srtmode', help='SRT mode for program return. Default is listener') parser.add_argument('--with-debug', dest='debug', action='store_true') args = parser.parse_args() returnport = "1234" if args.returnport: returnport = args.returnport srtmode = "&mode=listener" if args.srtmode: srtmode = args.srtmode srtoutput = "" if args.programreturn: srtoutput = "-f fifo -fifo_format mpegts -map 0:v:0 -map 0:a:0 -c copy srt://0.0.0.0:%s?pkt_size=1316%s" % (returnport, srtmode) ffmpeg = "ffmpeg -fflags +genpts -re -i %s -strict -2 -y %s " % (args.hlsurl, srtoutput) for dest in args.output: ffmpeg = ffmpeg + "-f fifo -fifo_format flv -map 0:v:0 -map 0:a:0 -c:v copy -vtag 7 -c:a copy -atag 10 -drop_pkts_on_overflow 1 -attempt_recovery 1 -recovery_wait_time 1 %s " % (dest) if args.debug: print "%s" % ffmpeg print ffmpeg.split() p1 = subprocess.Popen(ffmpeg.split()) output,err = p1.communicate() ================================================ FILE: python/hls2srt.py ================================================ #!/usr/bin/python2.7 # # Copyright 2019 Eyevinn Technology. All rights reserved # Use of this source code is governed by a MIT License # that can be found in the LICENSE file. # Author: Jonas Rydholm Birme (Eyevinn Technology) # # Receive HLS and stream over SRT # import argparse import subprocess from os.path import basename import re import glob parser = argparse.ArgumentParser(description='Pull HLS and restream over SRT.') parser.add_argument('hlsurl') parser.add_argument('address') parser.add_argument('--srtmode', dest='srtmode', help='SRT mode [caller|listener]. Default is listener') parser.add_argument('--with-debug', dest='debug', action='store_true') args = parser.parse_args() srtmode = "&mode=listener" if args.srtmode == "caller": srtmode = "" srtoutput = "-f mpegts srt://%s?pkt_size=1316%s" % (args.address, srtmode) ffmpeg = "ffmpeg -fflags +genpts -re -i %s -strict -2 -y -acodec copy -vcodec copy %s " % (args.hlsurl, srtoutput) if args.debug: print "%s" % ffmpeg print ffmpeg.split() p1 = subprocess.Popen(ffmpeg.split()) output,err = p1.communicate() ================================================ FILE: python/hls2ts.py ================================================ #!/usr/bin/python2.7 # # Copyright 2019 Eyevinn Technology. All rights reserved # Use of this source code is governed by a MIT License # that can be found in the LICENSE file. # Author: Jonas Rydholm Birme (Eyevinn Technology) # # Pull live HLS and output to multicast TS # import argparse import subprocess from os.path import basename import re import glob parser = argparse.ArgumentParser(description='Pull live HLS and output to multicast TS') parser.add_argument('hlsurl') parser.add_argument('outputaddress') parser.add_argument('--srt', action='store_true', help='use SRT as transport protocol') parser.add_argument('--channelbug', help='overlay logo as channel bug (poc)') parser.add_argument('--bitrate', help='which bitrate to use') parser.add_argument('--with-debug', dest='debug', action='store_true') args = parser.parse_args() protocol = 'udp' if args.srt: protocol = 'srt' bitrate = '' if args.bitrate: bitrate = "-map m:variant_bitrate:%s" % args.bitrate ffmpeg = "ffmpeg -fflags +genpts -re -i %s %s -strict -2 -y -vcodec copy -f mpegts %s://%s?pkt_size=1316" % (args.hlsurl, bitrate, protocol, args.outputaddress) if args.channelbug: ffmpeg = "ffmpeg -fflags +genpts -re -i %s -r 25 -i %s -filter_complex [0:1][1:v]#overlay=10:10:eval=init -c:v libx264 -preset ultrafast -strict -2 -y -f mpegts -max_muxing_queue_size 2048 %s://%s?pkt_size=1316" % (args.hlsurl, args.channelbug, protocol, args.outputaddress) arglist = ffmpeg.split() if args.debug: print "%s" % ffmpeg print map(lambda x: x.replace("#", " "), arglist) p1 = subprocess.Popen(map(lambda x: x.replace("#", " "), arglist)) output,err = p1.communicate() ================================================ FILE: python/loopts.py ================================================ #!/usr/bin/python2.7 # # Copyright 2019 Eyevinn Technology. All rights reserved # Use of this source code is governed by a MIT License # that can be found in the LICENSE file. # Author: Jonas Rydholm Birme (Eyevinn Technology) # # Loop input file and output to multicast TS # import argparse import subprocess from os.path import basename import re import glob parser = argparse.ArgumentParser(description='Loop an MP4 file and output to MPEG-TS multicast') parser.add_argument('inputfile') parser.add_argument('multicast') parser.add_argument('--workdir', help='specify a working directory, default is /mnt') parser.add_argument('--framerate', help='output framerate (DEFAULT 25fps)') parser.add_argument('--kfinterval', help='specify keyframe interval (DEFAULT 2 sec)') parser.add_argument('--bitrate', help='specify video bitrate in kbps (e.g. 2500)') parser.add_argument('--hevc', action='store_true', help='use HEVC encoded output') parser.add_argument('--withtc', action='store_true', help='burn in local timecode in video output') parser.add_argument('--withaudio', action='store_true', help='adds a test tone on the audio track') parser.add_argument('--nologo', action='store_true', help='remove logo') parser.add_argument('--useflv', action='store_true', help='use FLV for RTMP output') parser.add_argument('--multibitrate', action='store_true', help='output multiple video bitrates') parser.add_argument('--with-debug', dest='debug', action='store_true') args = parser.parse_args() workdir = '/mnt' if args.workdir: workdir = args.workdir framerate = '25' if args.framerate: framerate = args.framerate tcstr = '' framestr = '' if args.withtc: tcstr = ',drawtext=fontfile=/root/Vera.ttf:fontsize=200:text=\'%{localtime\\:%T}\':fontcolor=white@0.9:x=(w-tw)/2:y=250:shadowcolor=black:shadowx=2:shadowy=1' framestr = ',drawtext=fontfile=/root/Vera.ttf:fontsize=40:text=\'[%{n}/%{pts}]\':fontcolor=white@0.9:x=(w-tw)/2:y=h-th-10:shadowcolor=black:shadowx=2:shadowy=1' branding = 'drawtext=fontfile=/root/Vera.ttf:fontsize=12:text=\'eyevinntechnology/toolbox-loopts\':fontcolor=white@0.9:x=20:y=20:shadowcolor=black:shadowx=2:shadowy=1' if args.nologo: branding = '' audiostr = '-f lavfi -i anullsrc=r=48000:cl=stereo' if args.withaudio: audiostr = '-f lavfi -i sine=frequency=1000:sample_rate=48000' audiocopy = '-map 0:v -vcodec copy' kfinterval = float(framerate) * 2 forcekf = 2 if args.kfinterval: kfinterval = float(framerate) * float(args.kfinterval) forcekf = args.kfinterval streamidstr = '' overlayfilter = '-filter_complex [0:v]%s%s%s[overlay]' % (branding, tcstr, framestr) scalefilter = '[overlay]scale=1280:720[out720]' mapstr = '%s;%s -map [out720] -map 1:0' % (overlayfilter, scalefilter) bitratestr = '' if args.bitrate: bitratestr = '-b:v %sk -minrate %sk -maxrate %sk -bufsize %sk' % (args.bitrate, args.bitrate, args.bitrate, float(args.bitrate) / float(framerate)) outputencoding = '-vcodec libx264 -preset veryfast -pix_fmt yuv420p -g %s -keyint_min %s %s' % (kfinterval, kfinterval, bitratestr) if args.hevc: outputencoding = '-vcodec libx265 -preset superfast -pix_fmt yuv420p -g %s -keyint_min %s %s' % (kfinterval, kfinterval, bitratestr) if args.multibitrate: scalefilter = '[overlay]split=4[o1][o2][o3][o4];' scalefilter += '[o1]scale=480:360,drawtext=fontfile=/root/Vera.ttf:fontsize=12:text=\'480x360\':fontcolor=white@0.9:x=(w-tw)/2:y=20:shadowcolor=black:shadowx=2:shadowy=1[out360];' scalefilter += '[o2]scale=854:480,drawtext=fontfile=/root/Vera.ttf:fontsize=12:text=\'854x480\':fontcolor=white@0.9:x=(w-tw)/2:y=20:shadowcolor=black:shadowx=2:shadowy=1[out480];' scalefilter += '[o3]scale=1280:720,drawtext=fontfile=/root/Vera.ttf:fontsize=12:text=\'1280x720\':fontcolor=white@0.9:x=(w-tw)/2:y=20:shadowcolor=black:shadowx=2:shadowy=1[out720];' scalefilter += '[o4]scale=1920:1080,drawtext=fontfile=/root/Vera.ttf:fontsize=12:text=\'1920x1080\':fontcolor=white@0.9:x=(w-tw)/2:y=20:shadowcolor=black:shadowx=2:shadowy=1[out1080]' mapstr = '%s;%s -map [out360] -map 1:0 -map [out480] -map [out720] -map [out1080]' % (overlayfilter, scalefilter) outputencoding = '-c:v:0 libx264 -preset veryfast -pix_fmt yuv420p -g %s -keyint_min %s -force_key_frames expr:gte(t,n_forced*%s) -b:v:0 400k -maxrate 400k -bufsize %sk' % (kfinterval, kfinterval, forcekf, 400 / float(framerate)) outputencoding += ' -c:v:1 libx264 -preset veryfast -pix_fmt yuv420p -g %s -keyint_min %s -force_key_frames expr:gte(t,n_forced*%s) -b:v:1 1000k -maxrate 1000k -bufsize %sk' % (kfinterval, kfinterval, forcekf, 1000 / float(framerate)) outputencoding += ' -c:v:2 libx264 -preset veryfast -pix_fmt yuv420p -g %s -keyint_min %s -force_key_frames expr:gte(t,n_forced*%s) -b:v:2 2000k -maxrate 2000k -bufsize %sk' % (kfinterval, kfinterval, forcekf, 2000 / float(framerate)) outputencoding += ' -c:v:3 libx264 -preset veryfast -pix_fmt yuv420p -g %s -keyint_min %s -force_key_frames expr:gte(t,n_forced*%s) -b:v:3 4500k -maxrate 4500k -bufsize %sk' % (kfinterval, kfinterval, forcekf, 4500 / float(framerate)) outputformat = 'mpegts' if args.useflv: outputformat = 'flv' streamidstr = '' # ffmpeg -stream_loop -1 -i IN.mp4 -map 0:v -vcodec copy -bsf:v h264_mp4toannexb -f h264 - | ffmpeg -fflags +genpts -r 23.98 -re -i - -f lavfi -i anullsrc=r=48000:cl=stereo -c:a aac -shortest -vcodec libx264 -preset veryfast -pix_fmt yuv420p -strict -2 -y -f mpegts 'udp://239.0.0.1:1234' ffmpeg1 = "ffmpeg -stream_loop -1 -i %s/%s %s -bsf:v h264_mp4toannexb -f h264 -" % (workdir, args.inputfile, audiocopy) ffmpeg2 = "ffmpeg -thread_queue_size 512 -threads 4 -framerate %s -fflags +genpts -r %s -re -i - %s %s -c:a aac -shortest %s -strict -2 -y -f %s -r %s %s %s" % (framerate, framerate, audiostr, mapstr, outputencoding, outputformat, framerate, streamidstr, args.multicast) if args.debug: print "%s | %s" % (ffmpeg1, ffmpeg2) print ffmpeg1.split() print ffmpeg2.split() p1 = subprocess.Popen(ffmpeg1.split(), stdout=subprocess.PIPE) p2 = subprocess.Popen(ffmpeg2.split(), stdin=p1.stdout) p1.stdout.close() output,err = p2.communicate() ================================================ FILE: python/mosaicts.py ================================================ #!/usr/bin/python2.7 # # Copyright 2019 Eyevinn Technology. All rights reserved # Use of this source code is governed by a MIT License # that can be found in the LICENSE file. # Author: Jonas Rydholm Birme (Eyevinn Technology) # # Play multiple HLS sources and renders a mosaic in MPEG-TS # import argparse import subprocess from os.path import basename import re import glob import sys parser = argparse.ArgumentParser(description='Take multiple HLS sources and render a mosaic in MPEG-TS') parser.add_argument('layout', help='2x2|3x3') parser.add_argument('urlfile', help='A text file containing URLs to HLS sources. One source per line.') parser.add_argument('--port', default='9998') parser.add_argument('--multicast', help='Use multicast address specified here instead of SRT') parser.add_argument('--with-debug', dest='debug', action='store_true') args = parser.parse_args() if args.urlfile == '-': sources = [x.strip() for x in sys.stdin.readlines()] else: with open(args.urlfile, "r") as f: sources = [x.strip() for x in f.readlines()] scalex = 384 scaley = 216 width = 2 height = 2 if args.layout == '3x3': width = 3 height = 3 filter_complex = 'nullsrc=size=%dx%d [tmp0]; ' % (scalex * width, scaley * height) for i in range(0, width*height): filter_complex += '[%d:v] scale=%dx%d [s%d]; ' % (i, scalex, scaley, i) x = 0 y = 0 for i in range(0, width*height): if i < width*height - 1: filter_complex += '[tmp%d][s%d] overlay=shortest=1:x=%d:y=%d [tmp%d];' % (i, i, x, y, i + 1) else: filter_complex += '[tmp%d][s%d] overlay=shortest=1:x=%d:y=%d' % (i, i, x, y) if x >= (scalex * width) - scalex: y += scaley x = 0 else: x += scalex #print filter_complex inputs = '' for s in sources: inputs += '-i %s ' % s output = '"srt://0.0.0.0:%s?pkt_size=1316&mode=listener"' % args.port if args.multicast: output = 'udp://%s?pkt_size=1316' % args.multicast ffmpeg = 'ffmpeg -threads 8 -re %s -filter_complex "%s" -c:v libx264 -an -strict -2 -f mpegts %s' % (inputs, filter_complex, output) if args.debug: print "%s" % ffmpeg p1 = subprocess.Popen(ffmpeg, shell=True) output,err = p1.communicate() ================================================ FILE: python/rtmp2srt.py ================================================ #!/usr/bin/python2.7 # # Copyright 2020 Eyevinn Technology. All rights reserved # Use of this source code is governed by a MIT License # that can be found in the LICENSE file. # Author: Jonas Rydholm Birme (Eyevinn Technology) # # Receive RTMP and restream over SRT # import argparse import subprocess from os.path import basename import re import glob parser = argparse.ArgumentParser(description='Receive RTMP and restream over multicast') parser.add_argument('streamkey', help='RTMP stream key (path)') parser.add_argument('address', help='SRT address (IP:PORT)') parser.add_argument('--caller', dest='caller', action='store_true', help='SRT in caller mode (default listener)') parser.add_argument('--with-debug', dest='debug', action='store_true') args = parser.parse_args() mode = '&mode=listener' if args.caller: mode = '' if args.streamkey: mode += '&passphrase=' + args.streamkey ffmpeg = "ffmpeg -fflags +genpts -listen 1 -re -i rtmp://0.0.0.0/rtmp/%s -acodec copy -vcodec copy -strict -2 -y -f mpegts srt://%s?pkt_size=1316%s" % (args.streamkey, args.address, mode) if args.debug: print "%s" % ffmpeg print ffmpeg.split() p1 = subprocess.Popen(ffmpeg.split()) output,err = p1.communicate() ================================================ FILE: python/rtmprx.py ================================================ #!/usr/bin/python2.7 # # Copyright 2019 Eyevinn Technology. All rights reserved # Use of this source code is governed by a MIT License # that can be found in the LICENSE file. # Author: Jonas Rydholm Birme (Eyevinn Technology) # # Receive RTMP and restream over Multicast # import argparse import subprocess from os.path import basename import re import glob parser = argparse.ArgumentParser(description='Receive RTMP and restream over Multicast') parser.add_argument('inputstream') parser.add_argument('outputaddress') parser.add_argument('--passthrough', action='store_true', help='passthrough input and skip encoding process') parser.add_argument('--with-debug', dest='debug', action='store_true') args = parser.parse_args() outputcoding = '-acodec copy -vcodec libx264 -preset veryfast -pix_fmt yuv420p' if args.passthrough: outputcoding = '-acodec copy -vcodec copy' ffmpeg = "ffmpeg -fflags +genpts -listen 1 -re -i rtmp://0.0.0.0/live/%s %s -strict -2 -y -f mpegts udp://%s?pkt_size=1316" % (args.inputstream, outputcoding, args.outputaddress) if args.debug: print "%s" % ffmpeg print ffmpeg.split() p1 = subprocess.Popen(ffmpeg.split()) output,err = p1.communicate() ================================================ FILE: python/srt2rtmp.py ================================================ #!/usr/bin/python2.7 # # Copyright 2019 Eyevinn Technology. All rights reserved # Use of this source code is governed by a MIT License # that can be found in the LICENSE file. # Author: Jonas Rydholm Birme (Eyevinn Technology) # # Receive SRT and restream to multiple RTMP destinations # import argparse import subprocess from os.path import basename import re import glob parser = argparse.ArgumentParser(description='Receive SRT and restream to multiple RTMP destinations') parser.add_argument('inputaddress') parser.add_argument('output', nargs="+") parser.add_argument('--with-debug', dest='debug', action='store_true') args = parser.parse_args() ffmpeg = "ffmpeg -re -i srt://%s?pkt_size=1316&mode=listener -strict -2 -y " % (args.inputaddress) for dest in args.output: ffmpeg = ffmpeg + "-f fifo -fifo_format flv -map 0:0 -map 0:1? -c copy -vtag 7 -atag 10 -drop_pkts_on_overflow 1 -attempt_recovery 1 -recovery_wait_time 1 %s " % (dest) if args.debug: print "%s" % ffmpeg print ffmpeg.split() p1 = subprocess.Popen(ffmpeg.split()) output,err = p1.communicate() ================================================ FILE: python/srtrx.py ================================================ #!/usr/bin/python2.7 # # Copyright 2019 Eyevinn Technology. All rights reserved # Use of this source code is governed by a MIT License # that can be found in the LICENSE file. # Author: Jonas Rydholm Birme (Eyevinn Technology) # # Receive MPEG-TS over SRT and restream over Multicast # import argparse import subprocess from os.path import basename import re import glob parser = argparse.ArgumentParser(description='Receive MPEG-TS over SRT and restream over Multicast') parser.add_argument('inputaddress') parser.add_argument('outputaddress') parser.add_argument('--listener', action='store_true', help='run as SRT listener') parser.add_argument('--passthrough', action='store_true', help='for low latency skip the unmux and mux step.') parser.add_argument('--with-debug', dest='debug', action='store_true') args = parser.parse_args() listenermode = '' if args.listener: listenermode = '&mode=listener' if args.passthrough: ffmpeg = "srt-live-transmit srt://%s?pkt_size=1316%s udp://%s?pkt_size=1316" % (args.inputaddress, listenermode, args.outputaddress) else: ffmpeg = "ffmpeg -re -i srt://%s?pkt_size=1316%s -vcodec copy -acodec copy -strict -2 -y -f mpegts udp://%s?pkt_size=1316" % (args.inputaddress, listenermode, args.outputaddress) if args.debug: print "%s" % ffmpeg print ffmpeg.split() p1 = subprocess.Popen(ffmpeg.split()) output,err = p1.communicate() ================================================ FILE: python/srttx.py ================================================ #!/usr/bin/python2.7 # # Copyright 2019 Eyevinn Technology. All rights reserved # Use of this source code is governed by a MIT License # that can be found in the LICENSE file. # Author: Jonas Rydholm Birme (Eyevinn Technology) # # Receive RTMP and stream over SRT # import argparse import subprocess from os.path import basename import re import glob parser = argparse.ArgumentParser(description='Receive RTMP and stream over SRT') parser.add_argument('inputstream') parser.add_argument('outputaddress') parser.add_argument('--inputtype', default='rtmp', help='type of input [rtmp|mpegts], default is rtmp') parser.add_argument('--listener', action='store_true', help='run as SRT listener') parser.add_argument('--passthrough', action='store_true', help='passthrough input and skip encoding process') parser.add_argument('--analyzeduration', default='500000', help='set analyze duration for joining multicast TS') parser.add_argument('--with-debug', dest='debug', action='store_true') args = parser.parse_args() listenermode = '' if args.listener: listenermode = '&mode=listener' outputcoding = '-acodec copy -vcodec libx264 -preset veryfast -pix_fmt yuv420p' if args.passthrough: outputcoding = '-acodec copy -vcodec copy' inp = 'rtmp://0.0.0.0/live/%s -listen 1' % args.inputstream if args.inputtype == 'mpegts': inp = 'udp://%s?pkt_size=1316&overrun_nonfatal=1&fifo_size=50000000' % args.inputstream ffmpeg = "ffmpeg -fflags +genpts -re -analyzeduration %s -i %s %s -strict -2 -y -f mpegts srt://%s?pkt_size=1316%s" % (args.analyzeduration, inp, outputcoding, args.outputaddress, listenermode) if args.debug: print "%s" % ffmpeg print ffmpeg.split() p1 = subprocess.Popen(ffmpeg.split()) output,err = p1.communicate() ================================================ FILE: python/transcode.py ================================================ #!/usr/bin/python2.7 # # Copyright 2020 Eyevinn Technology. All rights reserved # Use of this source code is governed by a MIT License # that can be found in the LICENSE file. # Author: Jonas Rydholm Birme (Eyevinn Technology) # # Transcode an MP4 to multiple ABR-aligned MP4 files that can be packaged in various streaming formats # import argparse import subprocess from os.path import basename from os.path import splitext import re import glob parser = argparse.ArgumentParser(description='Transcode an MP4 file to multiple ABR-aligned MP4 files (AVC/AAC)') parser.add_argument('inputfile') parser.add_argument('--outdir', default='./', help="directory for the generated files. Default is current working directory.") parser.add_argument('--framerate', default=30, help="framerate of input file. Default to 30") args = parser.parse_args() ladder = [ (426, 240, 320), (854, 480, 960), (1280, 720, 1725), ] ffmpeg = "ffmpeg -y -i /media/%s " % args.inputfile for p in ladder: outputfile = "/media/%s-%s.mp4" % (splitext(args.inputfile)[0], p[2]) ffmpeg = ffmpeg + "-pix_fmt yuv420p -r %s -c:v libx264 -sc_threshold 0 -profile:v main -bf 1 -refs 3 -vf scale=w=%s:h=%s -b:v %sk -maxrate %sk -bufsize %sk -keyint_min %s -g %s -strict experimental -acodec aac -b:a 96k -f mp4 %s " % (args.framerate, p[0], p[1], p[2], p[2], p[2], args.framerate, (args.framerate * 2), outputfile) print ffmpeg p1 = subprocess.Popen(ffmpeg.split()) output,err = p1.communicate()