scuffle_flv/audio/header/
mod.rs

1//! FLV audio tag headers.
2
3use std::io::{self, Seek};
4
5use byteorder::ReadBytesExt;
6use bytes::Bytes;
7use enhanced::ExAudioTagHeader;
8use legacy::{LegacyAudioTagHeader, SoundFormat};
9
10use crate::error::FlvError;
11
12pub mod enhanced;
13pub mod legacy;
14
15/// FLV `AudioTagHeader`
16///
17/// This only describes the audio tag header, see [`AudioData`](super::AudioData) for the full audio data container.
18///
19/// Defined by:
20/// - Legacy FLV spec, Annex E.4.2.1
21/// - Enhanced RTMP spec, page 19, Enhanced Audio
22#[derive(Debug, Clone, PartialEq)]
23pub enum AudioTagHeader {
24    /// Legacy audio tag header.
25    Legacy(LegacyAudioTagHeader),
26    /// Enhanced audio tag header.
27    Enhanced(ExAudioTagHeader),
28}
29
30impl AudioTagHeader {
31    /// Demux the audio tag header from the given reader.
32    ///
33    /// If you want to demux the full audio data tag, use [`AudioData::demux`](super::AudioData::demux) instead.
34    /// This function will automatically determine whether the given data represents a legacy or an enhanced audio tag header
35    /// and demux it accordingly.
36    #[allow(clippy::unusual_byte_groupings)]
37    pub fn demux(reader: &mut io::Cursor<Bytes>) -> Result<Self, FlvError> {
38        let byte = reader.read_u8()?;
39        let sound_format = SoundFormat::from((byte & 0b1111_00_0_0) >> 4);
40        // Seek back one byte because we need the other half of the byte again
41        reader.seek_relative(-1)?;
42
43        if sound_format == SoundFormat::ExHeader {
44            ExAudioTagHeader::demux(reader).map(AudioTagHeader::Enhanced)
45        } else {
46            LegacyAudioTagHeader::demux(reader).map(AudioTagHeader::Legacy)
47        }
48    }
49}