Skip to main content

flowly_flv/
parser.rs

1use crate::{
2    error::Error, header::FlvHeader, reader::FlvReader, tag::video::mpeg4_avc::Mpeg4AvcParser,
3};
4
5mod tag;
6
7pub trait Parser<E, T> {
8    type Error;
9
10    fn parse(&mut self, reader: &mut impl FlvReader) -> Result<T, Self::Error>;
11}
12
13#[derive(Debug, Default, Clone)]
14pub struct FlvParser {
15    mpeg4_avc_parser: Option<Mpeg4AvcParser>,
16}
17
18impl<E> Parser<E, FlvHeader> for FlvParser {
19    type Error = Error<E>;
20
21    fn parse(&mut self, reader: &mut impl FlvReader) -> Result<FlvHeader, Self::Error> {
22        let mut signature = [0u8; 3];
23        reader.read_to_slice(&mut signature)?;
24
25        if &signature != b"FLV" {
26            return Err(Error::InvalidSignature);
27        }
28
29        let version = reader.read_u8()?;
30        let flags = reader.read_u8()?;
31
32        let is_audio_present = (flags & 0b00000100) != 0;
33        let is_video_present = (flags & 0b00000001) != 0;
34
35        let data_offset = reader.read_u32()?;
36
37        let remaining = data_offset.saturating_sub(9); // header size 3{FLV} + 1{version} + 1{flags} + 4{data_offset}
38
39        Ok(FlvHeader {
40            version,
41            is_audio_present,
42            is_video_present,
43            remaining,
44        })
45    }
46}