mirror of
https://github.com/rutgersc/m3u8-rs.git
synced 2024-05-19 08:48:09 +00:00
Update readme
This commit is contained in:
parent
39b52a1d4b
commit
210af70f72
131
README.md
131
README.md
|
@ -1,135 +1,10 @@
|
||||||
# m3u8-rs
|
# m3u8-rs
|
||||||
![crates.io](https://img.shields.io/crates/v/m3u8-rs.svg)
|
![crates.io](https://img.shields.io/crates/v/m3u8-rs.svg)
|
||||||
|
[![API](https://docs.rs/m3u8-rs/badge.svg)](https://docs.rs/m3u8-rs)
|
||||||
|
|
||||||
A Rust library for parsing m3u8 playlists (HTTP Live Streaming) [link](https://tools.ietf.org/html/draft-pantos-http-live-streaming-19).
|
A Rust library for parsing m3u8 playlists (HTTP Live Streaming) [link](https://datatracker.ietf.org/doc/html/rfc8216).
|
||||||
Uses the [`nom` library](https://github.com/Geal/nom) for all of the parsing.
|
Uses the [`nom` library](https://github.com/Geal/nom) for all of the parsing.
|
||||||
|
|
||||||
# Installation
|
|
||||||
To use this library, add the following dependency to `Cargo.toml`:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
m3u8-rs = "1.0.6"
|
|
||||||
```
|
|
||||||
|
|
||||||
Also available on [crates.io](https://crates.io/crates/m3u8-rs)
|
|
||||||
|
|
||||||
# Documentation
|
|
||||||
|
|
||||||
Available [here](https://rutgersc.github.io/doc/m3u8_rs/index.html)
|
|
||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
|
|
||||||
A simple example of parsing a playlist:
|
Examples can be found in the `examples` folder.
|
||||||
|
|
||||||
```rust
|
|
||||||
use m3u8_rs::playlist::Playlist;
|
|
||||||
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();
|
|
||||||
|
|
||||||
let parsed = m3u8_rs::parse_playlist_res(&bytes);
|
|
||||||
|
|
||||||
match parsed {
|
|
||||||
Ok(Playlist::MasterPlaylist(pl)) => println!("Master playlist:\n{}", pl),
|
|
||||||
Ok(Playlist::MediaPlaylist(pl)) => println!("Media playlist:\n{}", pl),
|
|
||||||
Err(e) => println!("Error: {:?}", e)
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
In the example above, `parse_playlist_res(&bytes)` returns a `Result<Playlist, IResult>`. It uses
|
|
||||||
the output of `parse_playlist(&bytes)` behind the scenes and just converts the `IResult` to a `Result`.
|
|
||||||
Here is an example of using the `parse_playlist(&bytes)` with `IResult` directly:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use m3u8_rs::playlist::Playlist;
|
|
||||||
use std::io::Read;
|
|
||||||
use nom::IResult;
|
|
||||||
|
|
||||||
let mut file = std::fs::File::open("playlist.m3u8").unwrap();
|
|
||||||
let mut bytes: Vec<u8> = Vec::new();
|
|
||||||
file.read_to_end(&mut bytes).unwrap();
|
|
||||||
|
|
||||||
let parsed = m3u8_rs::parse_playlist(&bytes);
|
|
||||||
|
|
||||||
match parsed {
|
|
||||||
IResult::Ok((i, Playlist::MasterPlaylist(pl))) => println!("Master playlist:\n{}", pl),
|
|
||||||
IResult::Ok((i, Playlist::MediaPlaylist(pl))) => println!("Media playlist:\n{}", pl),
|
|
||||||
IResult::Error(e) => panic!("Parsing error: \n{}", e),
|
|
||||||
IResult::Incomplete(e) => panic!("Parsing error: \n{:?}", e),
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Currently, the parser will succeed even if REQUIRED attributes/tags are missing from a playlist (such as the `#EXT-X-VERSION` tag).
|
|
||||||
The option to abort parsing when attributes/tags are missing may be something to add later on.
|
|
||||||
|
|
||||||
# Structure Summary
|
|
||||||
|
|
||||||
All the details about the structs are taken from https://tools.ietf.org/html/draft-pantos-http-live-streaming-19.
|
|
||||||
|
|
||||||
|
|
||||||
```rust
|
|
||||||
|
|
||||||
// Short summary of the important structs in playlist.rs:
|
|
||||||
//
|
|
||||||
pub enum Playlist {
|
|
||||||
MasterPlaylist(MasterPlaylist),
|
|
||||||
MediaPlaylist(MediaPlaylist),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MasterPlaylist {
|
|
||||||
pub version: usize,
|
|
||||||
pub variants: Vec<VariantStream>,
|
|
||||||
pub session_data: Option<SessionData>,
|
|
||||||
pub session_key: Option<SessionKey>,
|
|
||||||
pub start: Option<Start>,
|
|
||||||
pub independent_segments: bool,
|
|
||||||
pub alternatives: Vec<AlternativeMedia>,
|
|
||||||
pub unknown_tags: Vec<ExtTag>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MediaPlaylist {
|
|
||||||
pub version: usize,
|
|
||||||
pub target_duration: f32,
|
|
||||||
pub media_sequence: u64,
|
|
||||||
pub segments: Vec<MediaSegment>,
|
|
||||||
pub discontinuity_sequence: u64,
|
|
||||||
pub end_list: bool,
|
|
||||||
pub playlist_type: MediaPlaylistType,
|
|
||||||
pub i_frames_only: bool,
|
|
||||||
pub start: Option<Start>,
|
|
||||||
pub independent_segments: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct VariantStream {
|
|
||||||
pub is_i_frame: bool,
|
|
||||||
pub uri: String,
|
|
||||||
pub bandwidth: String,
|
|
||||||
pub average_bandwidth: Option<String>,
|
|
||||||
pub codecs: String,
|
|
||||||
pub resolution: Option<String>,
|
|
||||||
pub frame_rate: Option<String>,
|
|
||||||
pub audio: Option<String>,
|
|
||||||
pub video: Option<String>,
|
|
||||||
pub subtitles: Option<String>,
|
|
||||||
pub closed_captions: Option<String>,
|
|
||||||
pub alternatives: Vec<AlternativeMedia>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MediaSegment {
|
|
||||||
pub uri: String,
|
|
||||||
pub duration: f32,
|
|
||||||
pub title: Option<String>,
|
|
||||||
pub byte_range: Option<ByteRange>,
|
|
||||||
pub discontinuity: bool,
|
|
||||||
pub key: Option<Key>,
|
|
||||||
pub map: Option<Map>,
|
|
||||||
pub program_date_time: Option<String>,
|
|
||||||
pub daterange: Option<String>,
|
|
||||||
pub unknown_tags: Vec<ExtTag>,
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
Loading…
Reference in a new issue