17 stable releases

new 1.0.23 Mar 4, 2025
1.0.22 Feb 19, 2025
1.0.6 Jan 29, 2025

#50 in Command line utilities

Download history 253/week @ 2025-01-25 500/week @ 2025-02-01 392/week @ 2025-02-08 456/week @ 2025-02-15 63/week @ 2025-02-22 115/week @ 2025-03-01

1,122 downloads per month

MIT license

92KB
1.5K SLoC

HLS VOD to MPEG-TS UDP Re-cast

This Rust-based client reads from an HLS M3U8 playlist and rebroadcasts it as MPEG-TS over UDP. It is designed to handle the HLS produced by https://github.com/groovybits/mpegts_to_s3.git and is intended to be used as a relay for replaying that content.

To smooth the output using the LTN TS Tools Bitrate Smoother Rust Bindings https://github.com/LTNGlobal-opensource/libltntstools you must build with the smoother feature flag set.

Features

  • Read from HLS M3U8 playlists
  • Rebroadcast as MPEG-TS over UDP

Requirements

  • Rust (latest stable version)
  • Cargo (Rust package manager)
  • LibPcap
  • LibRdKafka development package for your OS
  • LibLTNTSTools (optional) Use the smoother feature flag to enable the Bitrate Smoother --features=smoother

Installation

  1. Build the project:
    cargo build --release --features=smoother
    

Live vs. VOD Mode vs. Multi-Hour VOD Mode

  • Live Mode: The client will read the M3U8 playlist and rebroadcast it as MPEG-TS over UDP.
  • VOD Mode: The client will read the M3U8 playlist and rebroadcast it as MPEG-TS over UDP, but will only send the segments between the start_time and end_time parameters.
  • Multi Hour VOD Mode: This mode enables extended playback by using an index of hour-based HLS playlists generated by udp-to-hls. The client will select and sequentially play segments spanning multiple hours based on the provided start and end times. This allows for seamless viewing of long-duration content, offering granular control over the playback period.

You need to set the --vod flag to enable VOD mode. The --start-time and --end-time flags are used to specify the start and end times in milliseconds for a single M3U8 Hour file. For multiple hours using --vod-date-starttime and --vod-date-endtime flags with formatted Date/Time values like "2025/02/26 22:50:00" used.

Format example of the hourly index file hourly_urls.log

  • The index file that udp-to-hls creates and can be used for the --vod-index <index_file> arg of hls-to-udp.

Date/Time Range for Channel01 on 2025/03/04 from the 08:00 to 09:00 hourly M3U8 playlists:

Hour channel01/2025/03/04/08 => http://192.168.50.55:9000/hls/channel01/2025/03/04/08/index.m3u8
Hour channel01/2025/03/04/09 => http://192.168.50.55:9000/hls/channel01/2025/03/04/09/index.m3u8

hls-to-udp Usage Examples

Template of running the client with the M3U8 URL and UDP address:

    hls-to-udp -u <M3U8_URL> -o <UDP_ADDRESS>:<UDP_PORT>

Basic Example:

    hls-to-udp -u http://example.com/playlist.m3u8 -o 224.0.0.200:10000

VOD Single hour m3u8 playback for the hour of 2025/02/05/05 between 10 and 120 seconds for that hour.

hls-to-udp -u "http://127.0.0.1:9000/hls/channel01/2025/02/05/05/index.m3u8/index.m3u8" \
    -o 224.0.0.200:4800 \
    --vod --start-time 10000 
    --end-time 120000

VOD Multiple hour span using the index created by udp-to-hls to get the hour m3u8's it created and playback only the start to end times given.

    hls-to-udp -o 224.0.0.200:10000 \
            --vod-index ../hourly_urls.log \
            --vod-date-starttime "2025/02/26 22:50:00" \
            --vod-date-endtime "2025/02/26 23:10:00" \
            --use-smoother \
            --vod

Help on command line usage (container and endpoint scripts take care of configuration usually)

Option(s) Description Default
-u, --m3u8-url <m3u8_url> URL to M3U8 playlist; must use either this or -i option (required)
-i, --vod-index <vod_index> Local file with index of VOD hour M3U8 playlists produced by udp-to-hls (hourly_urls.log); use with -s and -e (required)
-s, --vod-date-starttime <vod_date_starttime> VOD start date/time in 'YYYY/MM/DD HH:MM:SS' format (used with vod-index for VOD mode)
-e, --vod-date-endtime <vod_date_endtime> VOD end date/time in 'YYYY/MM/DD HH:MM:SS' format (used with vod-index for VOD mode)
-o, --udp-output <udp_output> UDP output address
-r, --use-smoother Use the PcrSmoother for rate control false
-d, --vod Enable VOD mode false
--m3u8-start-time-ms <start_time> Start time offset in milliseconds from start of M3U8 playlist for single URL/M3U8 VOD mode 0
--m3u8-end-time-ms <end_time> End time offset in milliseconds from start of M3U8 playlist for single URL/M3U8 VOD mode 0 (end of playlist)
-f, --output-file <output_file> Output file for debugging (empty)
-p, --poll-ms <poll_ms> Polling interval in milliseconds 100
--history-size <history_size> Size of history 999999
-v, --verbose Verbose level for output 0
-l, --latency Latency in milliseconds 2000
-c, --pcr-pid <pcr_pid> PCR PID (hexadecimal) 0x00
--smoother_buffers <smoother_buffers> Size of smoother buffers 5000
-k, --packet-size <packet_size> Packet size 1316
-m, --min-packet-size <min_packet_size> Minimum packet size 1316
-q, --segment-queue-size <segment_queue_size> Segment queue size 10
-z, --udp-queue-size <udp_queue_size> UDP queue size 512
-b, --udp-send-buffer <udp_send_buffer> UDP send buffer size 0 (OS default)
--max-bytes-threshold <max_bytes_threshold> Maximum bytes in smoother queue before reset 500_000_000
--quiet Suppress all non error output
--drop-corrupt-ts Drop corrupt TS packets
-h, --help Print help information
-V, --version Print version information

Optional Environment Variables for the container

- `HLS_INPUT_URL`: hls-to-udp input URL (default: `http://127.0.0.1:3001/channel01.m3u8`)
- `UDP_OUTPUT_IP`: hls-to-udp output IP for UDP (default: `224.0.0.200`)
- `UDP_OUTPUT_PORT`: hls-to-udp output port for UDP (default: `10000`)
- `SMOOTHER_LATENCY`: Bitrate Smoother latency in milliseconds (default: `1000`)
- `M3U8_UPDATE_INTERVAL_MS`: M3U8 update interval in milliseconds (default: `100`)
- `HLS_HISTORY_SIZE`: HLS history size (default: `1800`)
- `SEGMENT_QUEUE_SIZE`: Segment queue size (default: `32`)
- `UDP_QUEUE_SIZE`: UDP queue size (default: `1024`)
- `UDP_SEND_BUFFER`: Size of the UDP Send buffer (default: `0` - OS default)
- `USE_SMOOTHER`: Use the LibLTNTSTools Bitrate Smoother (default: `false`) Requires --features=smoother
- `HLS_TO_UDP_OUTPUT_FILE`: Output file for debugging (default: ``)

Container Deployment

  1. Build the container image:
    # The Dockerfile.replay and docker-compose.yaml are in the mpegts_to_s3 directory ../ below this one
    cd ../
    podman-compose up --build
    

Usage outside of a container

  1. Run the client with the M3U8 URL and UDP address:

    ./target/release/hls-to-udp -u <M3U8_URL> -o <UDP_ADDRESS>
    

    Example:

    ./target/release/hls-to-udp -u http://example.com/playlist.m3u8 -o 239.0.0.1:1234 -p 100
    

Author: wizard@groovy.org Date: January 27, 2025

Dependencies

~10–23MB
~337K SLoC