20 stable releases (5 major)

6.0.0 Feb 14, 2024
5.0.5 Dec 5, 2023
5.0.4 May 8, 2023
5.0.3 Dec 2, 2022
1.0.1 Jun 3, 2016

#18 in Video

Download history 2575/week @ 2024-01-25 2305/week @ 2024-02-01 2606/week @ 2024-02-08 2879/week @ 2024-02-15 2800/week @ 2024-02-22 2932/week @ 2024-02-29 3137/week @ 2024-03-07 3188/week @ 2024-03-14 3061/week @ 2024-03-21 3048/week @ 2024-03-28 3272/week @ 2024-04-04 3595/week @ 2024-04-11 3488/week @ 2024-04-18 4457/week @ 2024-04-25 3374/week @ 2024-05-02 2683/week @ 2024-05-09

14,648 downloads per month
Used in 24 crates (16 directly)

MIT license

80KB
2K SLoC

m3u8-rs

crates.io API

A Rust library for parsing m3u8 playlists (HTTP Live Streaming) link. Uses the nom library for all of the parsing.

Examples

Examples can be found in the examples folder.


lib.rs:

A library to parse m3u8 playlists HTTP Live Streaming.

Examples

Parsing a playlist and let the parser figure out if it's a media or master playlist.

use m3u8_rs::Playlist;
use nom::IResult;
use std::io::Read;

let mut file = std::fs::File::open("playlist.m3u8").unwrap();
let mut bytes: Vec<u8> = Vec::new();
file.read_to_end(&mut bytes).unwrap();

match m3u8_rs::parse_playlist(&bytes) {
    Result::Ok((i, Playlist::MasterPlaylist(pl))) => println!("Master playlist:\n{:?}", pl),
    Result::Ok((i, Playlist::MediaPlaylist(pl))) => println!("Media playlist:\n{:?}", pl),
    Result::Err(e) =>  panic!("Parsing error: \n{}", e),
}

Parsing a master playlist directly

use std::io::Read;
use nom::IResult;

let mut file = std::fs::File::open("masterplaylist.m3u8").unwrap();
let mut bytes: Vec<u8> = Vec::new();
file.read_to_end(&mut bytes).unwrap();

if let Result::Ok((_, pl)) = m3u8_rs::parse_master_playlist(&bytes) {
    println!("{:?}", pl);
}

Creating a playlist and writing it back to a vec/file

use m3u8_rs::{MediaPlaylist, MediaPlaylistType, MediaSegment};

let playlist = MediaPlaylist {
    version: Some(6),
    target_duration: 3,
    media_sequence: 338559,
    discontinuity_sequence: 1234,
    end_list: true,
    playlist_type: Some(MediaPlaylistType::Vod),
    segments: vec![
        MediaSegment {
            uri: "20140311T113819-01-338559live.ts".into(),
            duration: 2.002,
            title: Some("title".into()),
            ..Default::default()
        },
    ],
    ..Default::default()
};

//let mut v: Vec<u8> = Vec::new();
//playlist.write_to(&mut v).unwrap();

//let mut file = std::fs::File::open("playlist.m3u8").unwrap();
//playlist.write_to(&mut file).unwrap();

Controlling the output precision for floats, such as #EXTINF (default is unset)

use std::sync::atomic::Ordering;
use m3u8_rs::{WRITE_OPT_FLOAT_PRECISION, MediaPlaylist, MediaSegment};

WRITE_OPT_FLOAT_PRECISION.store(5, Ordering::Relaxed);

let playlist = MediaPlaylist {
    target_duration: 3,
    segments: vec![
        MediaSegment {
            duration: 2.9,
            title: Some("title".into()),
            ..Default::default()
        },
    ],
    ..Default::default()
};

let mut v: Vec<u8> = Vec::new();

playlist.write_to(&mut v).unwrap();
let m3u8_str: &str = std::str::from_utf8(&v).unwrap();
assert!(m3u8_str.contains("#EXTINF:2.90000,title"));

Dependencies

~1–1.4MB
~22K SLoC