On-line (Internet) Audio/Video

Index

General





IPTV Video over Internet
media video resolution
480i, 576i, 720p, 1080i, 1080p (any)
codec
  • MPEG-2
  • MPEG4-AVC/H264
  • VC-1
(any)
container
  • MPEG-2 TS
  • (direct)
  • MP4
  • QuickTime
  • WMedia
  • RealNetworks
  • Flash Video
  • ...
service discovery

SD&S
transmission progressive download
  • HTTP
  • FTP
- x
streaming live
video MPEG-2 RFC 2250
H264 RFC 3984
VC-1 RFC 4425
audio AAC RFC 3640
AMR-WB+ RFC 4352

x
on-demand x x
network delivery unicast
content on-demand x
multicast
x x
p2p
- x
receiver STB
x -
PC
  • Media Centre
  • browser (RTSP)
  • media player (RTP/RTCP)

Streaming

RTP

  • Problemes / Problems
  • Implementations:
  • SDP
    • SDP documents and standards
    • SDP in gstreamer
    • RTP audio video profile (wp)



    • info


      v=0
      c=IN IP4 ${destination_address}

      m=video ${video_rtp_port} RTP/AVP ${rtp_video_payload_type}
      a=rtpmap:${rtp_video_payload_type} H264/90000

      a=fmtp:${rtp_video_payload_type} ...


      m=audio ${audio_rtp_port} RTP/AVP ${rtp_audio_payload_type}
      a=rtpmap:${rtp_audio_payload_type} ${audio_media_subtype}/${rate}/${channels}

      a=fmtp:${rtp_audio_payload_type} ...
      video
      H.264
      m=video 5100 RTP/AVP 96
      a=rtpmap:96 H264/90000
      a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z2QAH6zZQFAFuhAAAAMAEAAAAwMA8YMZYA==,aOvssiw=; profile-level-id=64001F
      m=video 5100 RTP/AVP 96
      a=rtpmap:96 H264/90000
      a=fmtp:96 packetization-mode=1
      VP8
      m=video 5100 RTP/AVPF 96
      a=rtpmap:96 VP8/90000
      a=fmtp:96 max-fr=30; max-fs=3600;

      VP9
      m=video 5100 RTP/AVPF 96
      a=rtpmap:96 VP9/90000
      a=fmtp:96 max-fr=30; max-fs=3600


      audio AAC (48000Hz, 2 channels)
      m=audio 5102 RTP/AVP 97
      a=rtpmap:97 mpeg4-generic/48000/2


      opus (48000Hz, 2 channels) m=audio 5102 RTP/AVP 97
      a=rtpmap:97 opus/48000/2

      a=fmtp:97 sprop-stereo=1

    • SDP generats / Generated SDP:
      • when a single instance of ffmpeg generates several rtp streams, the option sdp-file contains all the streams. To split them, use the following script:
        • sdp_split.sh
          • #!/bin/bash

            common_sdp_path=$1

            common_sdp_dirname=$(dirname $common_sdp_path)
            common_sdp_basename=$(basename $common_sdp_path)
            common_sdp_name=${common_sdp_basename%.*}

            # remove all windows line feeds (^M)
            sed -i 's/\r//g' ${common_sdp_path}

            # get the number of video streams
            number_videos=$(grep "m=video" ${common_sdp_path} | wc -l)

            for (( video=1; video<=$number_videos; video++ ))
            do
                output_sdp_path="${common_sdp_dirname}/${common_sdp_name}_${video}.sdp"
                echo "${output_sdp_path}"

                awk -v selected_video=${video} '
            BEGIN {block=0; }
            #sub(/\r/,"", $0)
            /^v=/ {flag=1}
            /^s=/ {$0=$0 "_" selected_video}
            /^m=video/ {block++}
            flag {if (block==0 || block==selected_video) {print $0}}
            ' ${common_sdp_path} >${output_sdp_path}

            done
                   
            exit 0
      • RTP (vlc)
        • v=0
          o=- 15549874082820351558 15549874082820351558 IN IP4 localhost
          s=toto
          i=N/A
          c=IN IP4 234.1.2.3/255
          t=0 0
          a=tool:vlc 2.1.5
          a=recvonly
          a=type:broadcast
          a=charset:UTF-8

          m=audio 1234 RTP/AVP 96
          b=RR:0
          a=rtpmap:96 mpeg4-generic/48000/6
          a=fmtp:96 streamtype=5; profile-level-id=15; mode=AAC-hbr; config=11b0; SizeLength=13; IndexLength=3; IndexDeltaLength=3; Profile=1;

          m=video 1236 RTP/AVP 96
          b=RR:0
          a=rtpmap:96 H264/90000
          a=fmtp:96 packetization-mode=1;profile-level-id=64001f;sprop-parameter-sets=Z2QAH6zZgFAEWhAAAAMAEAAAAwMA8YMZoA==,aOl4TLIs;
      • TS over RTP (vlc)
        • v=0
          o=- 15549875101994746492 15549875101994746492 IN IP4 localhost
          s=toto
          i=N/A
          c=IN IP4 234.1.2.3/255
          t=0 0
          a=tool:vlc 2.1.5
          a=recvonly
          a=type:broadcast
          a=charset:UTF-8

          m=video 5004 RTP/AVP 33
          b=RR:0
          a=rtpmap:33 MP2T/90000
      • ffmpeg -f sap sap://234.1.2.3?same_port=0 (default)
        • v=0
          o=- 0 0 IN IP4 127.0.0.1
          s=Sintel
          t=0 0
          a=tool:libavformat 55.12.100

          m=video 5004 RTP/AVP 96
          c=IN IP4 234.1.2.3/255
          b=AS:1615
          a=rtpmap:96 H264/90000
          a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z2QAH6zZgFAEWhAAAAMAEAAAAwMA8YMZoA==,aOl4TLIs; profile-level-id=64001F

          m=audio 5006 RTP/AVP 97
          c=IN IP4 234.1.2.3/255
          b=AS:440
          a=rtpmap:97 MPEG4-GENERIC/48000/6
          a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=11B0
      • ffmpeg -f sap sap://234.1.2.3?same_port=1
        • v=0
          o=- 0 0 IN IP4 127.0.0.1
          s=Sintel
          t=0 0
          a=tool:libavformat 55.12.100

          m=video 5004 RTP/AVP 96
          c=IN IP4 234.1.2.3/255
          b=AS:1615
          a=rtpmap:96 H264/90000
          a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z2QAH6zZgFAEWhAAAAMAEAAAAwMA8YMZoA==,aOl4TLIs; profile-level-id=64001F

          m=audio 5004 RTP/AVP 97
          c=IN IP4 234.1.2.3/255
          b=AS:440
          a=rtpmap:97 MPEG4-GENERIC/48000/6
          a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=11B0
  • Tests (only video)




    • ffplay
      gstreamer




      generated SDP
      sdp
      sdp
      caps




      ffplay -protocol_whitelist rtp,udp,file,http,https,tcp,tls -i test.sdp gst-launch-1.0 filesrc location=test.sdp ! sdpdemux name=demux demux. ! queue ! decodebin ! autovideosink gst-launch-1.0 udpsrc address=127.0.0.1 port=5004 ! "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, packetization-mode=(string)1, profile-level-id=(string)64001f,  payload=(int)96" ! queue ! rtph264depay ! decodebin ! autovideosink gst-launch-1.0 udpsrc address=127.0.0.1 port=5004 ! "application/x-rtp, media=(string)video, clock-rate=(int)90000, encoding-name=(string)H264, packetization-mode=(string)1, profile-level-id=(string)64001f, sprop-parameter-sets=(string)\"...\", payload=(int)96" ! queue ! rtph264depay ! decodebin ! autovideosink
      ffmpeg
      test
      ffmpeg -re -f lavfi -i "testsrc=size=1280x720:rate=24" -c:v libx264 -b:v 700k -pix_fmt yuv420p -profile:v high -level:v 31 -f rtp rtp://127.0.0.1:5004 -sdp_file test.sdp
      SDP:
      v=0
      o=- 0 0 IN IP4 127.0.0.1
      s=No Name
      c=IN IP4 127.0.0.1
      t=0 0
      a=tool:libavformat 57.71.100
      m=video 5004 RTP/AVP 96
      b=AS:700
      a=rtpmap:96 H264/90000
      a=fmtp:96 packetization-mode=1
      correct
      correct
      There may be a timestamping problem, or this computer is too slow.
      • sprop from gstreamer test: correct
      • sprop from bbb: There may be a timestamping problem, or this computer is too slow.
      file
      ffmpeg -re -i bbb.mp4 -c:v copy -an -f rtp rtp://127.0.0.1:5004 -sdp_file test.sdp SDP:
      v=0
      o=- 0 0 IN IP4 127.0.0.1
      s=No Name
      c=IN IP4 127.0.0.1
      t=0 0
      a=tool:libavformat 57.71.100
      m=video 5004 RTP/AVP 96
      b=AS:698
      a=rtpmap:96 H264/90000
      a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z2QAH6zZQFAFuhAAAAMAEAAAAwMA8YMZYA==,aOvssiw=; profile-level-id=64001F
      correct
      videodecoder gstvideodecoder.c:2775:gst_video_decoder_prepare_finish_frame:<avdec_h264-0> decreasing timestamp (0:00:33.104109030 < 0:00:33.126489781)
      does not start playing
      • sprop from gstreamer test: correct
      • sprop from bbb: There may be a timestamping problem, or this computer is too slow.
      gstreamer
      test
      gst-launch-1.0 -v videotestsrc ! video/x-raw,framerate=24/1,width=1280,height=720 ! videoconvert ! x264enc ! video/x-h264,stream-format=byte-stream,profile=high ! rtph264pay config-interval=10 pt=96 ! udpsink host=127.0.0.1 port=5004 v=0
      o=- 0 0 IN IP4 127.0.0.1
      s=No Name
      c=IN IP4 127.0.0.1
      t=0 0
      a=tool:libavformat 57.71.100
      m=video 5004 RTP/AVP 96
      b=AS:700
      a=rtpmap:96 H264/90000
      a=fmtp:96 packetization-mode=1
      correct
      correct
      correct
      • sprop from gstreamer test: correct
      • sprop from bbb: There may be a timestamping problem, or this computer is too slow.
      file
      gst-launch-1.0 -v filesrc location=bbb_timecode_1280x720_700k_stereo.mp4 ! qtdemux name=demux demux.video_0 ! rtph264pay config-interval=10 pt=96 ! udpsink host=127.0.0.1 port=5004 v=0
      o=- 0 0 IN IP4 127.0.0.1
      s=No Name
      c=IN IP4 127.0.0.1
      t=0 0
      a=tool:libavformat 57.71.100
      m=video 5004 RTP/AVP 96
      b=AS:700
      a=rtpmap:96 H264/90000
      a=fmtp:96 packetization-mode=1
      correct
      videodecoder gstvideodecoder.c:2775:gst_video_decoder_prepare_finish_frame:<avdec_h264-0> decreasing timestamp (0:00:09.945574289 < 0:00:09.953238304)
      There may be a timestamping problem, or this computer is too slow.
      • sprop from gstreamer test: correct (!)
      • sprop from bbb (gstreamer verbose): There may be a timestamping problem, or this computer is too slow.

RTMP

  • RTMP (wp)
  • Estàndard / Standard
    • Adobe’s Real Time Messaging Protocol (pdf) (Dec 21 2012)
    • What is Real-Time Messaging Protocol (RTMP)?
      • handshake


    • nginx-rtmp-module logs
      header
      Basic Header (BH) RTMP bheader
      • Chunk Type / fmt
      • Stream ID / csid
      Chunk Message Header RTMP mheader
      • message size / mlen
      • Timestamp Delta / time
      • Message Type
        • 0x01 Set Packet Size Message
        • 0x02 Abort
        • 0x03 Acknowledge
        • 0x04 Control Message (not AMF encoded)
        • 0x05 Server Bandwidth
        • 0x06 Client Bandwidth
        • 0x07 Virtual Control
        • 0x08 Audio Packet / audio (8)
        • 0x09 Video Packet / video (9)
        • 0x0F Data Extended / (15)
        • 0x10 Container Extended / (16)
        • 0x11 Command Extended (am AMF3 type command) / (17)
        • 0x12 Data / meta (18)
        • 0x13 Container / (19)
        • 0x14 Command (An AMF0 type command) / amf_cmd (20)
          • commands
            standard
            nginx-rtmp-module log


            [debug] AMF func [info]
            7.2.1 NetConnection
            7.2.1.1 connect
            'connect'
            connect: app='my_app' args='' flashver='' swf_url='' tc_url='rtmp://192.168.1.138/my_app' page_url='' acodecs=0 vcodecs=0 object_encoding=0, client: 192.168.1.135, server: 0.0.0.0:1935
            7.2.1.2 Call

            7.2.1.3 createStream 'createstream' createStream, client: 192.168.1.135, server: 0.0.0.0:1935
            7.2.2 NetStream 7.2.2.1 play

            7.2.2.2 play2

            7.2.2.3 deleteStream 'deletestream' (1) deleteStream, client: 192.168.1.135, server: 0.0.0.0:1935
            7.2.2.4 receiveAudio

            7.2.2.5 receiveVideo

            7.2.2.6 publish 'publish' publish: name='sintel' args='' type=live silent=0, client: 192.168.1.135, server: 0.0.0.0:1935

            '@setdataframe' [debug] codec: data frame: width=640 height=360 duration=0 frame_rate=24 video=H264 (7) audio=AAC (10)
            7.2.2.7 seek

            7.2.2.8 pause

          • (1) [debug] AMF func 'deletestream' is not present when connection is closed by drop_idle_publisher: [error] live: drop idle publisher, client: 192.168.1.135, server: 0.0.0.0:1935
        • 0x15 UDP / (21)
        • 0x16 Aggregate / (22)
        • 0x17 Present / (23)




  • Timestamps
  • Ús / Usage

HTTP Streaming

  • Common Media Application Format - CMAF (MPEG)
  • MPEG-DASH
  • HTTP Live Streaming - HLS
    • HTTP Live Streaming draft-pantos-http-live-streaming (IETF)
    • HTTP Live Streaming Overview (Apple iPhone development center)
    • HLS Tags: Everything you need to know (MUX)
    • The HLS format (broadpeak.io)
    • codecs
      • video:
        • H.264/AVC baseline level 3.0
      • audio:
        • HE-AAC or AAC-LC up to 48 kHz, stereo audio
    • HTTP-Live-Video-Stream-Segmenter-and-Distributor (Carson McDonald)
    • iPhone HTTP Streaming with FFMpeg and an Open Source Segmenter
    • iPhone Windowed HTTP Live Streaming Using Amazon S3 and Cloudfront Proof of Concept
    • Streaming to the iPhone and iPod Touch (live, vod, multi-bitrate)
    • Streaming HowTo/Streaming for the iPhone (Videolan)
    • Galaxia HasDevTool
    • Best practices
      • Bit rate recommendations
        • "The first entry in the master playlist will be played at the initiation of a stream and is used as part of a test to determine which stream is most appropriate."
    • Xifratge / Encryption
    • Subtítols / Subtitles
      • convert srt to webvtt
        • ffmpeg -i en.srt -f webvtt en.webvtt
        • ffmpeg -i ca.srt -f webvtt ca.webvtt
      • index.m3u8
        • #EXTM3U
          #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="English",FORCED=NO,AUTOSELECT=YES,URI="en.ttml",LANGUAGE="en"
          #EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subs",NAME="Catalan",FORCED=NO,AUTOSELECT=YES,URI="ca.ttml",LANGUAGE="ca"
          #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=928000,RESOLUTION=640x360,SUBTITLES="subs"
          360p.m3u8
          #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2592000,RESOLUTION=1280x720,SUBTITLES="subs"
          720p.m3u8
          #EXT-X-ENDLIST
      • ca.ttml
        • #EXTM3U
          #EXT-X-VERSION:3
          #EXT-X-TARGETDURATION:3600
          #EXT-X-MEDIA-SEQUENCE:0
          #EXTINF:3600.0,
          ca.webvtt
          #EXT-X-ENDLIST
      • en.ttml
        • #EXTM3U
          #EXT-X-VERSION:3
          #EXT-X-TARGETDURATION:3600
          #EXT-X-MEDIA-SEQUENCE:0
          #EXTINF:3600.0,
          en.webvtt
          #EXT-X-ENDLIST
    • Monitor
      • AWS
        • Monitor HLS and DASH live streams using a canary monitor
          • aws-samples / monitor-hls-and-dash-streams-using-canary-monitor
            • Setup
              • AWS permissions
                • {
                      "Version": "2012-10-17",
                      "Statement": [
                          {
                              "Sid": "Statement1",
                              "Effect": "Allow",
                              "Action": [
                                  "cloudwatch:PutMetricData",
                                  "cloudwatch:ListDashboards",
                                  "cloudwatch:GetDashboard",
                                  "cloudwatch:DeleteDashboards",
                                  "cloudwatch:PutDashboard"
                              ],
                              "Resource": "*"
                          }
                      ]
                  }
              • script
                • config
                  • defaults.json
                    • ...
                • origins/demo.csv (all *.csv files in this dir will be read)
                  • # endpoint type (live), technology (hls/dash), workload name, endpoint name, origin name, monitoring config file, manifest url, tracking url [optional]
                    live, hls, my_workload, my_endpoint, my_origin, configs/default.json, https://myserver.org/path/to/index.m3u8
                    live, hls, lab, testendpoint, emp, configs/default.json, https://xxxxxx.mediapackage.us-west-2.amazonaws.com/out/v1/xxxxxx/index.mpd
            • Run
              • standalone
                • ./canarymonitor.py --region eu-west-1
              • service
                • canarymonitor.service
                  • ...
            • Generated files
              • archive
                • live
                  • my_workload
                    • my_origin
                      • my_endpoint
                        • hls
                          • reports
                            • <begin_datetime>_to_<end_datetime>.json
            • AWS CloudWatch
              • Dashboards > Custom dashboards > <WORKLOAD_NAME>-<Origin_name>-Canary-Monitor
                • verify that you have AWS permissions to manage  "cloudwatch:...Dashboards"
              • Metrics > All metrics > Browse > Custom namespaces > CanaryMonitor
                • Workload: ...
                • Endpoint
                • Origin
                • Rendition
                  • multi: index.m3u8
                  • v1: first_variant.m3u8
                • RequestType: manifest, ...
                • Technology: hls, dash
                • Type: live
                • Metric name: Latency, BufferFillDuration, ...
                • Alarms
      • Eyevinn
    • Eines / Tools
      • show cumulative time based on m3u8:
        • awk -F: '/^#EXTINF/ {gsub(/,/,"",$2); sum += $2; print $2 " " sum} /.ts/ {print $1} END {print sum}' monovariant.m3u8
      • hls_info.sh
        • #!/bin/bash

          m3u8_path=$1
          sum=0

          while read -r line
          do
              if [[ ${line} =~ ^"#EXTINF" ]]
              then
                  #echo ${line}
                  duration=$(echo ${line} | awk -F: '/^#EXTINF/ {gsub(/,/,"",$2); print $2}')
                  echo -n "---- start: ${sum} duration: ${duration} "
                  sum=$( echo "${sum}+${duration}" | bc -l)
                  echo -n "end: ${sum} "
              fi
             
              if [[ ${line} =~ "ts"$ ]]
              then
                  echo "<-- ${line}"
                  ffprobe -v 0 -show_entries frame=pkt_pts_time,pict_type -print_format compact=nk=1:p=0:s='\ ' -select_streams v:0 -i ${line}
              fi
             
          done < ${m3u8_path}

          echo "sum: ${sum}"

          exit 0
      • ts2m3u8.sh
        • #!/bin/bash

          function print_help_and_exit {
              cat <<EOF
          Usage: `basename $0` ts_dir ts_prefix ts_start ts_end

          Generate <ts_prefix>.gen.m3u8 file with reference to all ts files, in ts_dir, with file name:
          <ts_prefix><ts_start>.ts .. <ts_prefix><ts_stop>.ts

          Examples:
          - `basename $0` /tmp stream_low 4 55
          EOF
          }

          ts_dir=$1
          ts_prefix=$2
          ts_start=$3
          ts_end=$4

          function m3u8_header {
              # m3u8 header
              local m3u8_path=$1

              # TODO: calculate target duration from segments
             
              cat >${m3u8_path} <<EOF
          #EXTM3U
          #EXT-X-VERSION:3
          #EXT-X-TARGETDURATION:2
          #EXT-X-MEDIA-SEQUENCE:1
          EOF
          }

          function m3u8_footer {
              # m3u8 footer
              local m3u8_path=$1

              cat >>${m3u8_path} <<EOF
          #EXT-X-ENDLIST
          EOF
          }

          # output m3u8 file
          m3u8_path=${ts_prefix}.gen.m3u8

          # create m3u8 header
          m3u8_header ${m3u8_path}

          # get all ts files
          ts_list=$(eval ls -vx ${ts_dir}/${ts_prefix}{$ts_start..$ts_end}.ts)

          for ts_path in ${ts_list}
          do
              # get duration in seconds (with decimals)
              duration=$(ffprobe -i $ts_path -show_format -v quiet | sed -n 's/duration=//p')
              # keep only numbers and decimal point (discard N/A):
              duration=$(echo $duration | tr -d -c 0-9.)

              echo ${ts_path} ${duration}

              ts_basename=$(basename $ts_path)

              # put information into m3u8 output file
              echo "#EXTINF:${duration}," >>${m3u8_path}
              echo ${ts_basename} >>${m3u8_path}
          done

          # create m3u8 footer
          m3u8_footer ${m3u8_path}

          exit 0
    • FAST
      • Tools
        • Eyevinn Channel Engine (VOD2Live)
          • Create your own FAST Channels based on VOD2Live Technology and Open Source Components
            • Docker examples based on docker-fast
          • Components
            • Library: Eyevinn Channel Engine
            • Implementation with plugins: FAST by Eyevinn Technology (FAST Channel Engine)
              • Docker
              • Available plugins
                • Demo
                • ScheduleService
                  • manages channels and schedules
                  • uses AWS DynamoDB (it can be local)
                • Loop
                • Playlist
                • Barker
                • WebHook
              • ...

                info plugin docker plugin access FAST Engine docker docker compose
                docker compose up
                hls player
                Loop repeats a single url

                docker run --rm -it -p 8000:8000 \
                  -e FAST_PLUGIN=Loop \
                  -e LOOP_VOD_URL=<uri-to-hls-vod> \
                  -e LOOP_CHANNEL_NAME=testchannel \
                  eyevinntechnology/fast-engine

                http://localhost:8000/channels/testchannel/master.m3u8
                Playlist retrieves a playlist and plays it from the top (any static http server)
                E.g.: nginx
                docker run -it --rm -p 8888:80 \
                  -v /tmp/html:/usr/share/nginx/html --name web nginx
                Host file:
                /tmp/html/playlist.txt

                docker run --rm -it -p 8000:8000 \
                  -e FAST_PLUGIN=Playlist \
                  -e PLAYLIST_URL=http://<container_ip_address>:80/playlist.txt \
                  -e PLAYLIST_CHANNEL_NAME=testchannel \
                  eyevinntechnology/fast-engine
                docker-compose.yaml

                services:
                  web:
                    image: nginx
                    ports:
                      - 8888:80
                    volumes:
                      - /tmp/html:/usr/share/nginx/html
                  engine:
                    image: eyevinntechnology/fast-engine
                    environment:
                      - FAST_PLUGIN=Playlist
                      - PLAYLIST_URL=http://web/playlist.txt
                      - PLAYLIST_CHANNEL_NAME=testchannel
                    ports:
                      - 8000:8000
                http://localhost:8000/channels/testchannel/master.m3u8
                ScheduleService
                DynamoDB:
                docker run --rm -d -p 6000:8000 amazon/dynamodb-local

                ScheduleService:
                docker run --rm -p 8080:8080 \
                  -e DB=dynamodb://host.docker.internal:6000/eu-north-1 \
                  -e AWS_ACCESS_KEY_ID=null \
                  -e AWS_SECRET_ACCESS_KEY=null \
                  -e IF=0.0.0.0 \
                  eyevinntechnology/schedule-service
                API docs:
                http://localhost:8080/api/docs

                Channel list:
                curl -X 'GET' \
                  'http://localhost:8080/api/v1/channels' \
                  -H 'accept: application/json'

                Current schedule for channel eyevinn:
                curl -X 'GET' \
                  'http://localhost:8080/api/v1/channels/eyevinn/schedule?date=2023-03-06' \
                  -H 'accept: application/json'

                Create a new channel:
                curl -X 'POST' \
                  'http://localhost:8080/api/v1/channels' \
                  -H 'accept: application/json' \
                  -H 'Content-Type: application/json' \
                  -d '{
                  "id": "mychannel",
                  "tenant": "test",
                  "title": "My channel"
                }'
                docker run --rm -p 8000:8000 \
                  -e OPTS_USE_DEMUXED_AUDIO=false \
                  -e FAST_PLUGIN=ScheduleService \
                  -e SCHEDULE_SERVICE_API_URL=http://host.docker.internal:8080/api/v1 \
                  eyevinntechnology/fast-engine
                DynamoDB +
                ScheduleService +
                FAST Engine:
                docker-compose.yml
                http://localhost:8000/channels/eyevinn/master.m3u8
                http://localhost:8000/channels/mychannel/master.m3u8














Audio/Video

Descàrrega progressiva / Progressive download

Programari / Software

Maquinari / Hardware

Projectes europeus / European projects

Conferències / Conferences

Música / Music

Platform Components Technology Where / affiliates
Pressplay
(Duet)
  • Sony
  • Vivendi Universal
  • EMI
  • Madacy, Navarre, OWIE, Razor & Tie, Roadrunner, Rounder
  • TVT Records
  • Zomba

Musicnet

  • Virgin
  • HMV
Tornado

Xarxes CDN / Content Delivery Networks (CDN)

SRT Secure Reliable Transport

  • SRT Alliance
  • Info
  • Programari / Software
    • Biblioteques / Libraries
      • Haivision / srt (GitHub)
        • needed to be installed before compiling gstreamer, ffmpeg, sls
        • dependencies
          • Mageia
            • dnf install cmake tcl libopenssl-devel
          • CentOS
            • sudo yum install cmake tcl
        • compilació / compilation
          • cd src
          • git clone https://github.com/Haivision/srt.git
          • cd srt
          • ./configure
          • make
          • sudo make install
          • NOTE: srt.pc (needed by: pkg-config --exists srt) will be installed to /usr/local/lib64/pkgconfig/ . You may need to update environment variable accordingly before configuring the compilation of other packages:
            • export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig/:/usr/local/lib/pkgconfig/
          • update ldconfig
            • echo '/usr/local/lib64' >/etc/ld.so.conf.d/local64.conf
            • sudo ldconfig
        • eines / tools

    • encoders servers players
      software
      maquinari / hardware
      • Kiloview
        • RE-3


    • TSDuck
      • Instal·lació / Installation
        • from packages
        • from source (Building TSDuck)
          • git clone https://github.com/tsduck/tsduck.git
          • cd tsduck
          • git checkout v3.40-4165
          • sudo scripts/install-prerequisites.sh
          • make -j10 default docs-html
          • sudo make install
      • Transport Stream Utilities
      • Usage
    • MediaMTX
      • SRT
      • Escalabilitat / Scalability
      • ...


        publish from client publish from server play


        url configuration file (mediamrx.yml)
        url
        SRT
        SRT clients srt://localhost:8890?streamid=publish:mystream&pkt_size=1316
        • ffmpeg -re -stream_loop -1 -i file.ts -c copy -f mpegts 'srt://localhost:8890?streamid=publish:mystream&pkt_size=1316'

        srt://localhost:8890?streamid=read:mystream
        • FFmpeg and SRT
          • ffmpeg -i 'srt://localhost:8890?streamid=mystream:test' -c copy output.mp4

        SRT cameras and servers
        paths:
          proxied:
            # url of the source stream, in the format srt://host:port?streamid=streamid&other_parameters
            source: srt://original-url

        WebRTC
        WebRTC clients
        • WHIP (no web page): http://localhost:8889/mystream/whip
          • ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
            -f lavfi -i "sine=frequency=1000:sample_rate=48000" \
            -c:v libx264 -pix_fmt yuv420p -preset ultrafast -b:v 600k \
            -c:a libopus -ar 48000 -ac 2 -b:a 128k \
            -f whip http://localhost:8889/stream/whip
          • gst-launch-1.0 videotestsrc \
            ! video/x-raw,width=1920,height=1080,format=I420 \
            ! x264enc speed-preset=ultrafast bitrate=2000 \
            ! video/x-h264,profile=baseline \
            ! whipclientsink signaller::whip-endpoint=http://localhost:8889/mystream/whip
          • OBS Studio and WebRTC
          • Unity
            • /unity

        • web browser
        • WHEP (no whep browser)
          • http://localhost:8889/mystream/whep
          • GStreamer and WebRTC
            • gst-launch-1.0 whepsrc whep-endpoint=http://127.0.0.1:8889/stream/whep use-link-headers=true \
              video-caps="application/x-rtp,media=video,encoding-name=H264,payload=127,clock-rate=90000" \
              audio-caps="application/x-rtp,media=audio,encoding-name=PCMU,payload=0,clock-rate=8000" \
              ! rtph264depay ! decodebin ! autovideosink
          • Unity

        WebRTC servers

        yaml:
        paths:
          proxied:
            # url of the source stream, in the format whep://host:port/path (HTTP) or wheps:// (HTTPS)
            source: wheps://host:port/path

        if remote server is a MediaMTX server:
        paths:
          proxied:
            source: whep://host:port/mystream/whep

        RTSP
        RTSP clients
        rtsp://localhost:8554/mystream
        • ffmpeg -re -stream_loop -1 -i file.ts -c copy -f rtsp rtsp://localhost:8554/mystream
        • gst-launch-1.0 rtspclientsink name=s location=rtsp://localhost:8554/mystream \
          filesrc location=file.mp4 ! qtdemux name=d \
          d.video_0 ! queue ! s.sink_0 \
          d.audio_0 ! queue ! s.sink_1
        • OpenCV

        rtsp://localhost:8554/mystream
        • FFmpeg and RTSP
          • ffmpeg -i rtsp://localhost:8554/mystream -c copy output.mp4
        • GStreamer and RTSP
          • gst-launch-1.0 rtspsrc location=rtsp://127.0.0.1:8554/mystream latency=0 ! decodebin ! autovideosink
        • VLC
          • vlc --network-caching=50 rtsp://localhost:8554/mystream
        • OBS Studio

        RTSP cameras and servers

        yaml
        paths:
          proxied:
            # url of the source stream, in the format rtsp://user:pass@host:port/path
            source: rtsp://original-url
        /proxied
        RTMP RTMP clients rtmp://localhost/mystream
        • ffmpeg -re -stream_loop -1 -i file.ts -c copy -f flv rtmp://localhost:1935/mystream
        • gst-launch-1.0 -v flvmux name=mux ! rtmpsink location=rtmp://localhost/stream \
          videotestsrc ! video/x-raw,width=1280,height=720,format=I420 ! x264enc speed-preset=ultrafast bitrate=3000 key-int-max=60 ! video/x-h264,profile=high ! mux. \
          audiotestsrc ! audioconvert ! avenc_aac ! mux.
        • OBS studio and RTMP

        rtmp://localhost/mystream
        • FFmpeg and RTMP
          • ffmpeg -i rtmp://localhost/mystream -c copy output.mp4
          • ffmpeg -rtmp_enhanced_codecs ac-3,av01,avc1,ec-3,fLaC,hvc1,.mp3,mp4a,Opus,vp09 \
            -i rtmp://localhost/mystream -c copy output.mp4

        RTMP cameras and servers
        yaml
        paths:
          proxied:
            # url of the source stream, in the format rtmp://user:pass@host:port/path
            source: rtmp://original-url

        HLS HLS cameras and servers
        yaml
        paths:
          proxied:
            # url of the playlist of the stream, in the format http://user:pass@host:port/path
            source: http://original-url/stream/index.m3u8
        MPEG-TS MPEG-TS
        • udp+mpegts
          • ffmpeg -re -stream_loop -1 -i file.ts -c copy -f mpegts 'udp://127.0.0.1:3356?pkt_size=1316'
          • gst-launch-1.0 -v mpegtsmux name=mux alignment=1 ! udpsink host=238.0.0.1 port=1234 \
            videotestsrc ! video/x-raw,width=1280,height=720,format=I420 ! x264enc speed-preset=ultrafast bitrate=3000 key-int-max=60 ! video/x-h264,profile=high ! mux. \
            audiotestsrc ! audioconvert ! avenc_aac ! mux.
        • unix+mpegts
          • ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
            -c:v libx264 -pix_fmt yuv420p -preset ultrafast -b:v 600k \
            -f mpegts unix:/tmp/socket.sock
        udp+mpegts
        paths:
          mypath:
            source: udp+mpegts://238.0.0.1:1234
        unix+mpegts
        paths:
          mypath:
            source: unix+mpegts:///tmp/socket.sock

        RTP RTPhttps://mediamtx.org/docs/usage/publish#rtp
        • udp+rtp
          • ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
            -c:v libx264 -pix_fmt yuv420p -preset ultrafast -b:v 600k \
            -f rtp udp://238.0.0.1:1234?pkt_size=1316
        • unix+rtp
          • ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
            -c:v libx264 -pix_fmt yuv420p -preset ultrafast -b:v 600k \
            -f rtp unix:/tmp/socket.sock
        udp+rtp
        paths:
          mypath:
            source: udp+rtp://238.0.0.1:1234
            rtpSDP: |
              v=0
              o=- 123456789 123456789 IN IP4 192.168.1.100
              s=H264 Video Stream
              c=IN IP4 192.168.1.100
              t=0 0
              m=video 5004 RTP/AVP 96
              a=rtpmap:96 H264/90000
              a=fmtp:96 profile-level-id=42e01e;packetization-mode=1;sprop-parameter-sets=Z0LAHtkDxWhAAAADAEAAAAwDxYuS,aMuMsg==
        unix+rtp
        paths:
          mypath:
            source: unix+rtp:///tmp/socket.sock
            rtpSDP: |
              v=0
              o=- 123456789 123456789 IN IP4 192.168.1.100
              s=H264 Video Stream
              c=IN IP4 192.168.1.100
              t=0 0
              m=video 5004 RTP/AVP 96
              a=rtpmap:96 H264/90000
              a=fmtp:96 profile-level-id=42e01e;packetization-mode=1;sprop-parameter-sets=Z0LAHtkDxWhAAAADAEAAAAwDxYuS,aMuMsg==

        RPi Raspberry Pi cameras
        paths:
          cam:
            source: rpiCamera
        /cam

        Adding audio



        Secondary stream


        Webcam Generic webcams
        paths:
          cam:
            runOnInit: ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 -pix_fmt yuv420p -preset ultrafast -b:v 600k -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH
            runOnInitRestart: yes
        /cam
      • Documentation
    • SRS
    • SRT Live Server
      • fork pros
        cons
        Edward-Wu
        • stats not working
        • minor change to make it compile in Ubuntu 24.04 (make error #139):
          • sed -i '/#include <sys\/time.h>/ i #include <time.h>' slscore/common.cpp
        odensc
        • minor change to make it compile in Ubuntu 24.04 (make error #139):
          • sed -i '/#include <sys\/time.h>/ i #include <time.h>' slscore/common.cpp
        OpenIRL
        • stats not working
        irlserver
        • latest version (...) is not compiling
        • no git labels
        rstular

      • Docker
        • ravenium/srt-live-server (Docker Hub)
          • ravenium/srt-live-server (GitHub)
            • option a: from public repo DockerHub:
              • run container:
                • docker run -d -p 1935:1935/udp ravenium/srt-live-server
              • or run compose (not working on Mageia Linux):
                • mkdir -p logs; chmod a+w logs; docker compose up
            • option b: build your own image and run from it:
              1. clone repo
                • cd src
                • git clone https://github.com/ravenium/srt-live-server.git
                • cd srt-live-server
              2. build local image
                • docker build -t local-srt-live-server .
                • verify:
                  • docker image ls
              3. run container:
                • docker run -d -p 1935:1935/udp local-srt-live-server
                • verify that container is running:
                  • docker container ls -a
              4. or run from compose:
                • local-docker-compose.yaml
                  • version: '3'
                    services:
                      srt:
                        image: local-srt-live-server
                        ports:
                          - "1935:1935/udp"
                        volumes:
                          - ./sls.conf:/etc/sls/sls.conf
                          - ./logs:/logs
                • docker compose --file local-docker-compose.yml up
      • compilació / compilation
        • cd src
        • git clone https://github.com/Edward-Wu/srt-live-server.git
        • cd srt-live-server
        • # path to find libsrt
          export
          PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig/:/usr/local/lib/pkgconfig/
        • make
      • config
      • ús / usage
        • cd src/srt-live-server/bin
        • ./sls -c ../sls.conf
        • port=8080
        • server_ip="192.168.1.141"
        • transmit with ffmpeg (caller):
          • ffmpeg -re -f lavfi -i testsrc=size=320x240:r=15 -f lavfi -i anoisesrc=a=0.2 -c:v libx264 -profile:v baseline -b:v 1M -pix_fmt yuv420p -c:a aac -b:a 16k -f mpegts "srt://${server_ip}:${port}?streamid=uplive.sls.com/live/test"
        • transmit an existing file with srt-live-client (bin/slc)
          • ./slc -r srt://${server_ip}:${port}?streamid=uplive.sls.com/live/test -i source_file.ts
        • transmit with obs (compiled wit srt-enabled ffmpeg):
          • Server: srt://192.168.1.141:8080?streamid=uplive.sls.com/live/test
          • Key: (empty)
        • receive with ffplay (caller):
          • ffplay -i "srt://${server_ip}:${port}?streamid=live.sls.com/live/test"
        • receive with srt-live-client (bin/slc) and generate a file:
          • ./slc -r srt://${server_ip}:${port}?streamid=live.sls.com/live/test -o destination_file.ts
      • estadístiques / statistics
        • NOTE: use odensc fork
        • sls.conf
          • srt {
                stat_post_url http://127.0.0.1/unit/sls/stat ;
                stat_post_interval 5;
            }
        • unit behind nginx
          • unit.conf
            • location /unit/ {
                  proxy_pass http://127.0.0.1:8090/;
                  proxy_set_header Host $host;
                  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              }
        • /etc/fastapi/
          • asgi.py
            • from pathlib import Path

              from fastapi import FastAPI, Request
              from fastapi.templating import Jinja2Templates
              from pydantic import BaseModel


              app = FastAPI()

              # variable to store the values received by post
              app.statistics = []

              # absolute path for templates
              BASE_DIR = Path(__file__).resolve().parent
              templates = Jinja2Templates(directory=str(Path(BASE_DIR, "templates")))


              class Statistics(BaseModel):
                  port: str
                  role: str
                  pub_domain_app: str
                  stream_name: str
                  url: str
                  remote_ip: str
                  remote_port: str
                  start_time: str
                  kbitrate: str

              @app.get("/sls/statistics")
              async def get_statistics(request: Request):
                  """
                  Return html table with statistics
                  """
                  # print(app.statistics)
                  context = [st.dict() for st in app.statistics]
                  return templates.TemplateResponse(
                      request=request,
                      name="statistics.html",
                      context={"statistics": context},
                  )


              @app.get("/sls/stat")
              async def get_stat():
                  return app.statistics


              @app.post("/sls/stat")
              async def post_stat(statistics: list[Statistics]):
                  # curl -i -X POST -H 'Content-Type: application/json' --data '[{"port": "8080","role": "player","pub_domain_app": "uplive.sls.com/live","stream_name": "test","url": "live.sls.com/live/test","remote_ip": "192.168.1.146","remote_port": "60788","start_time": "2025-04-25 17:54:43","kbitrate": "1724"}]' http://localhost:8090/sls/stat
                  # sample body:
                  # [
                  #     {
                  #         "port": "8080",
                  #         "role": "player",
                  #         "pub_domain_app": "uplive.sls.com/live",
                  #         "stream_name": "test",
                  #         "url": "live.sls.com/live/test",
                  #         "remote_ip": "192.168.1.146",
                  #         "remote_port": "60788",
                  #         "start_time": "2025-04-25 17:54:43",
                  #         "kbitrate": "1724",
                  #     },
                  #     {
                  #         "port": "8080",
                  #         "role": "publisher",
                  #         "pub_domain_app": "uplive.sls.com/live",
                  #         "stream_name": "test",
                  #         "url": "uplive.sls.com/live/test",
                  #         "remote_ip": "192.168.1.146",
                  #         "remote_port": "36141",
                  #         "start_time": "2025-04-25 17:53:45",
                  #         "kbitrate": "1745",
                  #     },
                  #     {
                  #         "port": "8080",
                  #         "role": "listener",
                  #         "pub_domain_app": "",
                  #         "stream_name": "",
                  #         "url": "",
                  #         "remote_ip": "",
                  #         "remote_port": "",
                  #         "start_time": "2025-04-25 17:52:31",
                  #         "kbitrate": "0",
                  #     },
                  # ]

                  # body = await request.body()
                  # print(body)
                  # return {"status": "OK"}

                  app.statistics = statistics
                  return statistics


              @app.post("/sls/on_event")
              async def on_event(
                  on_event: str, role_name: str, srt_url: str, remote_ip: str, remote_port: int
              ):
                  # "POST /sls/on_event?on_event=on_connect&role_name=publisher&srt_url=publish/stream/fa0c67a2d70bb2c2-5464f06ed01a6b6e&remote_ip=139.47.125.46&remote_port=39642 HTTP/1.1" 200 OK
                  # "POST /sls/on_event?on_event=on_close&role_name=publisher&srt_url=publish/stream/fa0c67a2d70bb2c2-5464f06ed01a6b6e&remote_ip=139.47.125.46&remote_port=39642 HTTP/1.1" 200 OK
                  # on_event=on_connect
                  # role_name=publisher
                  # srt_url=publish/stream/fa0c67a2d70bb2c2-5464f06ed01a6b6e&
                  # remote_ip=139.47.125.46
                  # remote_port=39642
                  # body = await request.body()
                  # print(body)
                  print("  on_event: {}".format(on_event))
                  print("  role_name: {}".format(role_name))
                  print("  srt_url: {}".format(srt_url))
                  print("  remote_ip: {}".format(remote_ip))
                  print("  remote_port: {}".format(remote_port))

                  return {"status": "OK"}
          • templates/statistics.html
            • <html>
              <head>
                  <title>Statistics</title>
              </head>
              <body>
                  <h1>Statistics</h1>
                  <table border="1">
                      <tr>
                          <th>port</th>
                          <th>role</th>
                          <th>pub_domain_app</th>
                          <th>stream_name</th>
                          <th>url</th>
                          <th>remote_ip</th>
                          <th>remote_port</th>
                          <th>start_time</th>
                          <th>kbitrate</th>
                      </tr>
                      {% for stat in statistics %}
                      <tr>
                          <td>{{ stat.port }}</td>
                          <td>{{ stat.role }}</td>
                          <td>{{ stat.pub_domain_app }}</td>
                          <td>{{ stat.stream_name }}</td>
                          <td>{{ stat.url }}</td>
                          <td>{{ stat.remote_ip }}</td>
                          <td>{{ stat.remote_port }}</td>
                          <td>{{ stat.start_time }}</td>
                          <td>{{ stat.kbitrate }}</td>
                      </tr>
                      {% endfor %}
                     
                  </table>
              </body>
              </html>
        • set config
          • ...
        • get config:
          • curl -X GET --unix-socket /var/run/control.unit.sock http://localhost:8090/config/
        • get statistics:
          • http://my_server/unit/sls/statistics
    • modes (Medium: SRT)
      mode host port
      caller remote host remote port
      listener
      local listening port
      rendezvous other public host local and remote port
    • ...

      conf publish play
      SLS (Edward-Wu) # sls.conf
      server {
        listen 8080;

        domain_player live.sls.com live-1.sls.com;
        domain_publisher uplive.sls.com;

        app {
          app_player live;
          app_publisher live;
        }
      }
      srt://[your.sls.ip]:8080?streamid=uplive.sls.com/live/test srt://[your.sls.ip]:8080?streamid=live.sls.com/live/test
      SLS (OpenIRL) # sls.conf
      server {
        listen 4001;

        domain_player play;
        domain_publisher publish;

        app {
          app_player stream;
          app_publisher stream;
        }
      }
      srt://[your.sls.ip]:4001?streamid=publish/stream/test srt://[your.sls.ip]:4001?streamid=play/stream/test
      MediaMTX # mediamtx.yml
      • custom streamid syntax
        • srt://localhost:8890?streamid=publish:mystream&pkt_size=1316
        • srt://localhost:8890?streamid=publish:mystream:user:pass&pkt_size=1316
      • standard streamid syntax (SRT Access Control (Stream ID) Guidelines):
        • srt://localhost:8890?streamid=#!::m=publish,r=mypath,u=myuser,s=mypass&pkt_size=1316
          • m=<mode: publish, request, bidirectional>
          • r=<resource_name>
          • u=<username>
          • s=<session_id>
          • h=<host_name>
          • t=<type: stream, file, auth>
      • custom streamid syntax
        • srt://localhost:8890?streamid=read:mystream
        • srt://localhost:8890?streamid=read:mystream:user:pass
      • standard streamid syntax:
        • ...

    • transmitter Tx receiver Rx

      gst-launch-1.0 -v videotestsrc ! "video/x-raw,height=360,width=640" ! videoconvert ! x264enc tune=zerolatency ! "video/x-h264,profile=baseline" ! mpegtsmux ! srtsink uri="srt://:8888/" gst-launch-1.0 -v srtsrc uri=srt://127.0.0.1:8888 ! decodebin ! autovideosink

      ffmpeg -re -f lavfi -i testsrc=size=320x240:r=15 -f lavfi -i sine=f=440:b=1 -c:v libx264 -profile:v baseline -b:v 1M -pix_fmt yuv420p -c:a aac -b:a 16k -f mpegts srt://:8888
      ffplay srt://127.0.0.1:8888
      • transmitter is a client
        (caller)
      • receiver is a server
        (listener; should be started first)
      • port=9998
      • receiver_ip="192.168.1.141"
      • ffmpeg ... -f mpegts "srt://${receiver_ip}:${port}?pkt_size=1316"
      • from test source:
        • ffmpeg -re -f lavfi -i testsrc=size=320x240:r=15 -f lavfi -i anoisesrc=a=0.2 -c:v libx264 -profile:v baseline -b:v 1M -pix_fmt yuv420p -c:a aac -b:a 16k -f mpegts "srt://${receiver_ip}:${port}?pkt_size=1316"
        • gst-launch-1.0 -v videotestsrc ! "video/x-raw,height=360,width=640" ! videoconvert ! x264enc tune=zerolatency ! "video/x-h264,profile=baseline" ! mpegtsmux ! srtsink uri="srt://${receiver_ip}:${port}/"
      • transmux from udp:
        • ffmpeg -fflags +genpts -listen 1 -re -i udp://239.0.0.1:1234?pkt_size=1316 -acodec copy -vcodec copy -strict -2 -y -f mpegts "srt://${receiver_ip}:${port}?pkt_size=1316"
      • port=9998
      • ffplay -i "srt://0.0.0.0:${port}?pkt_size=1316&mode=listener"
      • ffmpeg -re -i "srt://0.0.0.0:${port}?pkt_size=1316&mode=listener" ...
      • gst-launch-1.0 -v srtsrc uri="srt://:${port}" mode=listener ! decodebin ! autovideosink
      • transmux to udp:
        • ffmpeg -re -i "srt://0.0.0.0:${port}?pkt_size=1316&mode=listener" -vcodec copy -acodec copy -strict -2 -y -f mpegts udp://239.0.0.2:1234?pkt_size=1316
      • transmitter is a server
        (listener; should be started first)
      • receiver is a client
        (caller)
      • port=9998
      • ffmpeg ... -f mpegts "srt://0.0.0.0:${port}?pkt_size=1316&mode=listener"
      • from test source:
        • ffmpeg -re -f lavfi -i testsrc=size=320x240:r=15 -f lavfi -i anoisesrc=a=0.2 -c:v libx264 -profile:v baseline -b:v 1M -pix_fmt yuv420p -c:a aac -b:a 16k -f mpegts "srt://0.0.0.0:${port}?pkt_size=1316&mode=listener"
        • gst-launch-1.0 -v videotestsrc ! "video/x-raw,height=360,width=640" ! videoconvert ! x264enc tune=zerolatency ! "video/x-h264,profile=baseline" ! mpegtsmux ! srtsink uri="srt://${receiver_ip}:${port}/" mode=listener
      • transmux from udp (e.g. 239.0.0.1:1234):
        • ffmpeg -fflags +genpts -listen 1 -re -i udp://239.0.0.1:1234?pkt_size=1316 -acodec copy -vcodec copy -strict -2 -y -f mpegts "srt://0.0.0.0:${port}?pkt_size=1316&mode=listener"
      • port=9998
      • transmitter_ip="192.168.1.141"
      • ffplay -i "srt://${transmitter_ip}:${port}?pkt_size=1316"
      • ffmpeg -re -i "srt://${transmitter_ip}:${port}?pkt_size=1316" ...
      • gst-launch-1.0 -v srtsrc uri="srt://${transmitter_ip}:${port}" ! decodebin ! autovideosink
      • transmux to udp:
        • ffmpeg -re -i "srt://${transmitter_ip}:${port}?pkt_size=1316" -vcodec copy -acodec copy -strict -2 -y -f mpegts udp://239.0.0.2:1234?pkt_size=1316
      • rendezvous
      • port=9998
      • receiver_public_ip="192.168.1.141"
      • from test source:
        • ffmpeg -re -f lavfi -i testsrc=size=320x240:r=15 -f lavfi -i anoisesrc=a=0.2 -c:v libx264 -profile:v baseline -b:v 1M -pix_fmt yuv420p -c:a aac -b:a 16k -f mpegts "srt://${receiver_public_ip}:${port}?pkt_size=1316&mode=rendezvous"
      • port=9998
      • transmitter_public_ip="192.168.1.141"
      • ffplay -i "srt://${transmitter_public_ip}:${port}?pkt_size=1316&mode=rendezvous"
    • NOTE: use pkt_size=1316 to allocate 7 TS packets into one IP packet: 188*7=1316 < 1500
    • Problemes / Problems

RIST Reliable Internet Stream Transport

Gestió de drets / Rights Management (DRM)

Signatura / Signature

Xifratge / Encryption

  • Estaǹdards / Standards
  • Eines / Tools

    command (Bento4)
    standard
    encrypt
    decrypt
    DCF
    mp4dcfpackager --method CTR
    --content-id cid:toto
    --key 000102030405060708090a0b0c0d0e0f:00000000000000000000000000000000
    toto.mp4 toto.dcf
    mp4decrypt
    --key 1:00112233445566778899aabbccddeeff
    toto.dcf toto.odf
    mp4extract toto.odf
    PDCF
    mp4encrypt --method OMA-PDCF-CTR
    --key 1:000102030405060708090a0b0c0d0e0f:0000000000000000
    --key 2:000102030405060708090a0b0c0d0e0f:0000000000000000
    toto.mp4 toto.pdcf
    mp4decrypt
    --key 1:000102030405060708090a0b0c0d0e0f:0000000000000000
    --key 2:000102030405060708090a0b0c0d0e0f:0000000000000000
    toto.pdcf toto.mp4

Gestió de pagaments / Payment management

Formats (*)

Continguts / Contents

Seqüències / Sequencies

P2P (Peer to peer)

Reproductors MP3 Players



dim LCD ràdio recording bluetooth video doc preu





dim res colors FM RDS FM line mic


1GB
(Z)
2GB (Q) 4GB
(A)










live prog







Samsung YP-F2R 28 52 15


x x -
-






YP-T7 37 62 14
96x96 65K - - -
-
-




YP-T7F 37 62 14 1,2" 96x96 262K x x x x x
- MPEG4
135, 138+9+iva

YP-T8 44 83 15 1,8" 128x160 262K x - x


-


169
YP-T9J
(unoff)
43 83 11 1,8" 172x220 262K x x x - - x x SVI: XVID 208x176 15 fps pdf 169+9+iva 155+9,9ii
189+9+iva
169+22ii
239+9+iva
199+22ii
YP-Z5F 42 90 12 1,8" 128x160
x x x
-

MPEG4
118 159, 149
F: FM
X: 512MB
Z: 1GB
Q: 2GB
A: 4GB

http://www.francescpinyol.cat/online_audio_video.html
Darrera modificació: 30 de novembre de 2025 / Last update: 30th November 2025

Cap a casa / Back home.