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}