|
- #ifndef _hls_parser_h_
- #define _hls_parser_h_
-
- #include <stdint.h>
- #include <stddef.h>
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- enum
- {
- HLS_M3U8_UNKNOWN = 0,
- HLS_M3U8_PLAYLIST,
- HLS_M3U8_MASTER,
- };
-
- enum
- {
- HLS_PLAYLIST_TYPE_LIVE = 0,
- HLS_PLAYLIST_TYPE_EVENT,
- HLS_PLAYLIST_TYPE_VOD,
- };
-
- enum
- {
- HLS_MEDIA_UNKNOWN = 0,
- HLS_MEDIA_AUDIO,
- HLS_MEDIA_VIDEO,
- HLS_MEDIA_SUBTITLE,
- HLS_MEDIA_CLOSED_CAPTIONS,
- };
-
- // #EXT-X-MEDIA
- struct hls_media_t
- {
- char* type; // audio/video/subtitle/closed-captions
- char* uri; // Media Playlist file, If the TYPE is CLOSED-CAPTIONS, the URI attribute MUST NOT be present.
-
- char* group_id;
- char* language; // RFC5645
- char* assoc_language;
- char* name;
- char* instream_id; // CC1, SERVICE1, for HLS_MEDIA_CLOSED_CAPTIONS
- char* characteristics; // public.accessibility.describes-video
- char* channels; // for HLS_MEDIA_AUDIO
-
- int autoselect; // 1-YES, 0-NO
- int is_default; // 1-YES, 0-NO
- int forced; // 1-YES, 0-NO, SUBTITLES only
- };
-
- // #EXT-X-STREAM-INF
- struct hls_variant_t
- {
- uint32_t bandwidth; // the peak segment bit rate of the Variant Stream
- uint32_t average_bandwidth; // the average segment bit rate of the Variant Stream
- int width, height; // resolution
- double fps; // frame-rate
- char* hdcp_level; // TYPE-0
- char* uri;
- char* codecs; // RFC6381, mp4a.40.2,avc1.4d401e
- char* video_range; // SDR/PQ
- char* audio; // GROUP-ID of EXT-X-MEDIA
- char* video; // GROUP-ID of EXT-X-MEDIA
- char* subtitle; // GROUP-ID of EXT-X-MEDIA
- char* closed_captions; // GROUP-ID of EXT-X-MEDIA
-
- struct hls_variant_t* i_frame_stream_inf; // EXT-X-I-FRAME-STREAM-INF
- };
-
- struct hls_segment_t
- {
- double duration;
- char* uri;
- char* title;
-
- int64_t bytes; // EXT-X-BYTERANGE, -1 if don't exist
- int64_t offset; // EXT-X-BYTERANGE, -1 if don't exist
-
- // 1. file format
- // 2. number, type, and identifiers of tracks
- // 3. timestamp sequence
- // 4. encoding parameters
- // 5. encoding sequence
- int discontinuity; // EXT-X-DISCONTINUITY
-
- struct {
- char* method; // NONE, AES-128, and SAMPLE-AES
- char* uri;
- char* keyformat; // identity
- char* keyformatversions; // "1", "1/2", "1/2/5"
- uint8_t iv[16]; // 128bits
- } key; // EXT-X-KEY
-
- // It applies to every Media Segment that appears after it in the
- // Playlist until the next EXT-X-MAP tag or until the end of the Playlist.
- struct {
- char* uri;
- int64_t bytes; // BYTERANGE, -1 if don't exist
- int64_t offset; // BYTERANGE, -1 if don't exist
- } map; // EXT-X-MAP
-
- char* program_date_time; // EXT-X-PROGRAM-DATE-TIME
-
- struct {
- char* id;
- char* cls;
- char* start_date;
- char* end_date;
- double duration; // decimal-floating-point number of seconds
- double planned_duration; // decimal-floating-point number of seconds
- char* x_client_attribute; // TODO
- int end_on_next; // 1-YES, 0-NO
- } daterange; // EXT-X-DATERANGE
- };
-
- // If the Media Playlist contains the EXT-X-MEDIA-SEQUENCE tag, the
- // client SHOULD assume that each Media Segment in it will become
- // unavailable at the time that the Playlist file was loaded plus the
- // duration of the Playlist file.
- struct hls_playlist_t
- {
- int version;
-
- uint64_t target_duration; // EXT-X-TARGETDURATION, seconds
- uint64_t media_sequence; // EXT-X-MEDIA-SEQUENCE, base from 0
- uint64_t discontinuity_sequence; // EXT-X-DISCONTINUITY-SEQUENCE, decimal-integer
- int endlist; // EXT-X-ENDLIST, 1-endlist, 0-don't have endlist
- int type; // EXT-X-PLAYLIST-TYPE, 0-LIVE, 1-EVENT, 2-VOD
- int i_frames_only; // EXT-X-I-FRAMES-ONLY
- int independent_segments; // EXT-X-INDEPENDENT-SEGMENTS
- double start_time_offset; // EXT-X-START, seconds
- int start_precise; // EXT-X-START
-
- struct hls_segment_t* segments;
- size_t count;
- };
-
- struct hls_master_t
- {
- int version;
-
- size_t variant_count;
- struct hls_variant_t *variants;
-
- // renditions: audio, video, subtitle, close_captions
- size_t media_count;
- struct hls_media_t* medias;
-
- struct {
- char* data_id;
- char* value;
- char* uri;
- char* language;
- } *session_data;
- size_t session_data_count;
-
- struct {
- char* method; // NONE, AES-128, and SAMPLE-AES
- char* uri;
- char* keyformat; // identity
- char* keyformatversions; // "1", "1/2", "1/2/5"
- uint8_t iv[16]; // 128bits
- } *session_key; // EXT-X-SESSION-KEY
- size_t session_key_count;
-
- int independent_segments; // EXT-X-INDEPENDENT-SEGMENTS
- double start_time_offset; // EXT-X-START
- int start_precise; // EXT-X-START
- };
-
- /// Probe m3u8 content type(HLS_M3U8_MASTER/HLS_M3U8_PLAYLIST)
- /// @return 1-master playlist, 2-media playlist, other-unknown
- int hls_parser_probe(const char* m3u8, size_t len);
-
- /// Parse m3u8 master playlist
- /// @param[out] master m3u8 master playlist(free by hls_master_free)
- /// @return 0-ok, other-error
- int hls_master_parse(struct hls_master_t** master, const char* m3u8, size_t len);
-
- int hls_master_free(struct hls_master_t** master);
-
- int hls_master_best_variant(const struct hls_master_t* master);
-
- int hls_master_rendition(const struct hls_master_t* master, int variant, int type, const char* name);
-
- /// Parse m3u8 media playlist
- /// @param[out] playlist m3u8 media playlist(free by hls_playlist_free)
- /// @return 0-ok, other-error
- int hls_playlist_parse(struct hls_playlist_t** playlist, const char* m3u8, size_t len);
-
- int hls_playlist_free(struct hls_playlist_t** playlist);
-
- /// @return total duration in MS
- int64_t hls_playlist_duration(const struct hls_playlist_t* playlist);
-
- #ifdef __cplusplus
- }
- #endif
- #endif /* !_hls_parser_h_ */
|