use std::io;
use byteorder::{BigEndian, ReadBytesExt};
use bytes::Bytes;
use scuffle_bytes_util::BytesCursorExt;
use crate::error::FlvError;
#[derive(Debug, Clone, PartialEq)]
pub struct FlvHeader {
pub version: u8,
pub is_audio_present: bool,
pub is_video_present: bool,
pub extra: Bytes,
}
impl FlvHeader {
pub fn demux(reader: &mut io::Cursor<Bytes>) -> Result<Self, FlvError> {
let start = reader.position() as usize;
let signature = reader.read_u24::<BigEndian>()?;
if signature != u32::from_be_bytes([0, b'F', b'L', b'V']) {
return Err(FlvError::InvalidSignature(signature));
}
let version = reader.read_u8()?;
let flags = reader.read_u8()?;
let is_audio_present = (flags & 0b00000100) != 0;
let is_video_present = (flags & 0b00000001) != 0;
let data_offset = reader.read_u32::<BigEndian>()?;
let end = reader.position() as usize;
let size = end - start;
let remaining = (data_offset as usize)
.checked_sub(size)
.ok_or(FlvError::InvalidDataOffset(data_offset))?;
let extra = reader.extract_bytes(remaining)?;
Ok(FlvHeader {
version,
is_audio_present,
is_video_present,
extra,
})
}
}