flv_rs/core/
mod.rs

1mod amf;
2mod converter;
3
4use std::{convert::TryInto, fmt, fs::File, io::{Read, Seek, Write}};
5
6use linked_hash_map::LinkedHashMap;
7use log::{debug, error, trace};
8
9use crate::{core::{
10        amf::{Value, AMF},
11        converter::ConvertBytes,
12    }, io::{DataReader, IOError}};
13
14pub(crate) const FLV_TAG_TYPE_AUDIO: u8 = 8;
15pub(crate) const FLV_TAG_TYPE_VIDEO: u8 = 9;
16pub(crate) const FLV_TAG_TYPE_SCRIPT: u8 = 18;
17pub(crate) const FLV_SCRIPT_TYPE_NUMBER: u8 = 0;
18pub(crate) const FLV_SCRIPT_TYPE_BOOLEAN: u8 = 1;
19pub(crate) const FLV_SCRIPT_TYPE_STRING: u8 = 2;
20pub(crate) const FLV_SCRIPT_TYPE_OBJECT: u8 = 3;
21pub(crate) const FLV_SCRIPT_TYPE_MOVIE_CLIP: u8 = 4;
22pub(crate) const FLV_SCRIPT_TYPE_NULL: u8 = 5;
23pub(crate) const FLV_SCRIPT_TYPE_UNDEFINED: u8 = 6;
24pub(crate) const FLV_SCRIPT_TYPE_REFERENCE: u8 = 7;
25pub(crate) const FLV_SCRIPT_TYPE_ECMA_ARRAY: u8 = 8;
26pub(crate) const FLV_SCRIPT_TYPE_SCRIPT_DATA_OBJECT_END: u8 = 9;
27pub(crate) const FLV_SCRIPT_TYPE_STRICT_ARRAY: u8 = 10;
28pub(crate) const FLV_SCRIPT_TYPE_DATE: u8 = 11;
29pub(crate) const FLV_SCRIPT_TYPE_LONG_STRING: u8 = 12;
30
31pub(crate) const FLV_SOUND_RATE_TABLE: [u32; 5] = [5500, 11025, 22050, 44100, 48000];
32pub(crate) const MPEG_SAMPLING_RATES: [u32; 13] = [
33    96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350,
34];
35pub(crate) const MPEG_AUDIO_V10_SAMPLE_RATE_TABLE: [u32; 4] = [44100, 48000, 32000, 0];
36pub(crate) const MPEG_AUDIO_V20_SAMPLE_RATE_TABLE: [u32; 4] = [22050, 24000, 16000, 0];
37pub(crate) const MPEG_AUDIO_V25_SAMPLE_RATE_TABLE: [u32; 4] = [11025, 12000, 8000, 0];
38pub(crate) const MPEG_AUDIO_L1_BIT_RATE_TABLE: [i16; 16] = [
39    0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1,
40];
41pub(crate) const MPEG_AUDIO_L2_BIT_RATE_TABLE: [i16; 14] = [
42    0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, -1,
43];
44pub(crate) const MPEG_AUDIO_L3_BIT_RATE_TABLE: [i16; 12] =
45    [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, -1];
46
47pub(crate) const FLV_VIDEO_FRAME_TYPE_KEY_FRAME: u8 = 1;
48pub(crate) const FLV_VIDEO_FRAME_TYPE_INTER_FRAME: u8 = 2;
49pub(crate) const FLV_VIDEO_FRAME_TYPE_DISPOSABLE_INTER_FRAME: u8 = 3;
50pub(crate) const FLV_VIDEO_FRAME_TYPE_GENERATED_KEY_FRAME: u8 = 4;
51pub(crate) const FLV_VIDEO_FRAME_TYPE_VIDEO_INFO_OR_COMMAND_FRAME: u8 = 5;
52
53pub(crate) const FLV_VIDEO_CODEC_ID_SORENSON_H263: u8 = 2;
54pub(crate) const FLV_VIDEO_CODEC_ID_SCREEN_VIDEO: u8 = 3;
55pub(crate) const FLV_VIDEO_CODEC_ID_ON2_VP6: u8 = 4;
56pub(crate) const FLV_VIDEO_CODEC_ID_ON2_VP6_WITH_ALPHA_CHANNEL: u8 = 5;
57pub(crate) const FLV_VIDEO_CODEC_ID_SCREEN_VIDEO_VERSION_2: u8 = 6;
58pub(crate) const FLV_VIDEO_CODEC_ID_AVC: u8 = 7;
59
60pub(crate) const FLV_AVC_PACKAGE_TYPE_AVC_SEQUENCE_HEADER: u8 = 0;
61pub(crate) const FLV_AVC_PACKAGE_TYPE_AVC_NALU: u8 = 1;
62pub(crate) const FLV_AVC_PACKAGE_TYPE_AVC_END_OF_SEQUENCE: u8 = 2;
63
64pub(crate) const FLV_AUDIO_SOUND_FORMAT_LINEAR_PCM_PLATFORM_ENDIAN: u8 = 0;
65pub(crate) const FLV_AUDIO_SOUND_FORMAT_ADPCM: u8 = 1;
66pub(crate) const FLV_AUDIO_SOUND_FORMAT_MP3: u8 = 2;
67pub(crate) const FLV_AUDIO_SOUND_FORMAT_LINEAR_PCM_LITTLE_ENDIAN: u8 = 3;
68pub(crate) const FLV_AUDIO_SOUND_FORMAT_NELLYMOSER_16KHZ_MONO: u8 = 4;
69pub(crate) const FLV_AUDIO_SOUND_FORMAT_NELLYMOSER_8KHZ_MONO: u8 = 5;
70pub(crate) const FLV_AUDIO_SOUND_FORMAT_NELLYMOSER: u8 = 6;
71pub(crate) const FLV_AUDIO_SOUND_FORMAT_G711_A_LAW_LOGARITHMIC_PCM: u8 = 7;
72pub(crate) const FLV_AUDIO_SOUND_FORMAT_G711_MU_LAW_LOGARITHMIC_PCM: u8 = 8;
73pub(crate) const FLV_AUDIO_SOUND_FORMAT_RESERVED: u8 = 9;
74pub(crate) const FLV_AUDIO_SOUND_FORMAT_AAC: u8 = 10;
75pub(crate) const FLV_AUDIO_SOUND_FORMAT_SPEEX: u8 = 11;
76pub(crate) const FLV_AUDIO_SOUND_FORMAT_MP3_8KHZ: u8 = 14;
77pub(crate) const FLV_AUDIO_SOUND_FORMAT_DEVICE_SPECIFIC_: u8 = 15;
78// pub(crate) const FLV_AUDIO_SOUND_FORMAT_LINEAR_PCM: u8 = 14;
79// pub(crate) const FLV_AUDIO_SOUND_FORMAT_LINEAR_PCM: u8 = 15;
80
81pub(crate) const FLV_AUDIO_SOUND_RATE_5D5K: u8 = 0;
82pub(crate) const FLV_AUDIO_SOUND_RATE_11K: u8 = 1;
83pub(crate) const FLV_AUDIO_SOUND_RATE_22K: u8 = 2;
84pub(crate) const FLV_AUDIO_SOUND_RATE_44K: u8 = 3;
85
86pub(crate) const FLV_AUDIO_SOUND_SIZE_8B: u8 = 0;
87pub(crate) const FLV_AUDIO_SOUND_SIZE_16B: u8 = 1;
88
89pub(crate) const FLV_AUDIO_SOUND_TYPE_MONO: u8 = 0;
90pub(crate) const FLV_AUDIO_SOUND_TYPE_STEREO: u8 = 1;
91
92pub(crate) const FLV_AAC_PACKET_TYPE_AAC_SEQUENCE_HEADER: u8 = 0;
93pub(crate) const FLV_AAC_PACKET_TYPE_AAC_RAW: u8 = 1;
94
95#[derive(Debug)]
96pub enum FLVError {
97    ParseError(String),
98    TypeError(Value, String),
99    Complete,
100    None,
101    WriteError(String),
102}
103
104impl fmt::Display for FLVError {
105    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106        match self {
107            Self::ParseError(msg) => write!(f, "flv file error: {}", msg),
108            Self::TypeError(v, msg) => write!(f, "type {} error: {}", v, msg),
109            Self::Complete => write!(f, "Complete"),
110            Self::None => write!(f, "None"),
111            Self::WriteError(msg) => write!(f, "write flv file error {}", msg),
112        }
113    }
114}
115
116#[derive(Debug, Clone)]
117pub struct TagHeader {
118    pub tag_type: u8,
119    pub data_size: u32,
120    pub timestamp_base: u32,
121    pub timestamp_extended: u32,
122    pub stream_id: u32,
123}
124
125impl TagHeader {
126    pub fn timestamp(&self) -> u32 {
127        self.timestamp_extended << 24 | self.timestamp_base
128    }
129}
130
131impl ConvertBytes for TagHeader {
132    type T = u8;
133    fn to_bytes(&self) -> Vec<Self::T> {
134        let mut bytes = Vec::new();
135        bytes.push(self.tag_type);
136        bytes.append(&mut self.data_size.to_be_bytes()[1..].to_vec());
137        bytes.append(&mut self.timestamp_base.to_be_bytes()[1..].to_vec());
138        bytes.push(self.timestamp_extended as u8);
139        bytes.append(&mut self.stream_id.to_be_bytes()[1..].to_vec());
140        bytes
141    }
142}
143
144#[derive(Debug, Clone)]
145pub struct Keyframes {
146    pub times: Vec<f64>,
147    pub file_positions: Vec<f64>,
148}
149
150impl ConvertBytes for Keyframes {
151    type T = u8;
152
153    fn to_bytes(&self) -> Vec<Self::T> {
154        let mut val = vec![0, 0x9];
155        val.append(&mut "keyframes".as_bytes().to_vec());
156        val.append(&mut vec![0x3, 0, 0xD]);
157        val.append(&mut "filepositions".as_bytes().to_vec());
158        val.push(FLV_SCRIPT_TYPE_STRICT_ARRAY);
159        val.append(&mut (self.file_positions.len() as u32).to_be_bytes().to_vec());
160        for fp in &self.file_positions {
161            val.push(FLV_SCRIPT_TYPE_NUMBER);
162            val.append(&mut fp.to_be_bytes().to_vec());
163        }
164        val.append(&mut vec![0, 0x5]);
165        val.append(&mut "times".as_bytes().to_vec());
166        val.push(FLV_SCRIPT_TYPE_STRICT_ARRAY);
167        val.append(&mut (self.times.len() as u32).to_be_bytes().to_vec());
168        for t in &self.times {
169            val.push(FLV_SCRIPT_TYPE_NUMBER);
170            val.append(&mut t.to_be_bytes().to_vec())
171        }
172        val
173    }
174}
175
176#[derive(Clone, Debug)]
177pub struct Metadata {
178    keyframes: Option<Keyframes>,
179    data: LinkedHashMap<String, Value>,
180}
181
182impl Metadata {
183    pub fn new() -> Metadata {
184        Metadata {
185            data: LinkedHashMap::new(),
186            keyframes: None,
187        }
188    }
189
190    pub fn get(&self, key: &str) -> Option<&Value> {
191        match self.data.get(&key.to_string()) {
192            Some(v) => Some(v),
193            None => None,
194        }
195    }
196
197    pub fn set(&mut self, key: &str, value: Value) {
198        self.data.insert(key.to_string(), value);
199    }
200
201    pub fn len(&self) -> usize {
202        self.data.len()
203    }
204
205    pub fn get_f64(&self, key: &str) -> Result<&f64, FLVError> {
206        match self.data.get(&key.to_string()) {
207            Some(Value::Number(v)) => Ok(v),
208            Some(v) => Err(FLVError::TypeError(
209                v.clone(),
210                format!("type must be Number").to_string(),
211            )),
212            None => Err(FLVError::None),
213        }
214    }
215
216    pub fn get_bool(&self, key: &str) -> Result<&bool, FLVError> {
217        match self.data.get(&key.to_string()) {
218            Some(Value::Boolean(v)) => Ok(v),
219            Some(v) => Err(FLVError::TypeError(
220                v.clone(),
221                format!("can not convert {} to bool", v),
222            )),
223            None => Err(FLVError::None),
224        }
225    }
226
227    pub fn get_string(&self, key: &str) -> Result<&String, FLVError> {
228        match self.data.get(&key.to_string()) {
229            Some(Value::LongString(v)) | Some(Value::Strings(v)) => Ok(v),
230            Some(v) => Err(FLVError::TypeError(v.clone(), format!(""))),
231            None => Err(FLVError::None),
232        }
233    }
234
235    pub fn get_vec(&self, key: &str) -> Result<&Vec<Value>, FLVError> {
236        match self.data.get(&key.to_string()) {
237            Some(Value::EcmaArray(v)) | Some(Value::StrictArray(v)) => Ok(v),
238            Some(v) => Err(FLVError::TypeError(v.clone(), format!(""))),
239            None => Err(FLVError::None),
240        }
241    }
242
243    pub fn get_map(&self, key: &str) -> Result<&LinkedHashMap<String, Value>, FLVError> {
244        match self.data.get(&key.to_string()) {
245            Some(Value::Object(v)) => Ok(v),
246            Some(v) => Err(FLVError::TypeError(v.clone(), format!(""))),
247            None => Err(FLVError::None),
248        }
249    }
250}
251
252impl ConvertBytes for Metadata {
253    type T = u8;
254    fn to_bytes(&self) -> Vec<Self::T> {
255        let mut bytes = vec![FLV_SCRIPT_TYPE_STRING, 0, 0xA];
256        bytes.append(&mut String::from("onMetaData").into_bytes());
257        bytes.push(FLV_SCRIPT_TYPE_ECMA_ARRAY);
258        let count = match self.keyframes {
259            Some(_) => self.len() + 1,
260            None => self.len(),
261        };
262        bytes.append(&mut (count as u32).to_be_bytes().to_vec());
263        for (k, v) in self.data.iter() {
264            bytes.append(&mut (k.len() as u16).to_be_bytes().to_vec());
265            bytes.append(&mut k.as_bytes().to_vec());
266            bytes.append(&mut v.to_bytes());
267        }
268
269        if !matches!(self.keyframes, None) {
270            bytes.append(&mut self.keyframes.as_ref().unwrap().to_bytes());
271        }
272        bytes.append(&mut vec![0, 0, FLV_SCRIPT_TYPE_SCRIPT_DATA_OBJECT_END, 0, 0, FLV_SCRIPT_TYPE_SCRIPT_DATA_OBJECT_END]);
273        bytes
274    }
275}
276
277#[derive(Debug, Clone)]
278pub struct SPS {
279    pub sps_length: u16,
280    pub sps_nal_unit: Vec<u8>,
281}
282
283impl ConvertBytes for SPS {
284    type T = u8;
285    fn to_bytes(&self) -> Vec<Self::T> {
286        let mut val = self.sps_length.to_be_bytes().to_vec();
287        val.append(&mut self.sps_nal_unit.clone());
288        val
289    }
290}
291
292/// Sequence Parameter Set
293#[derive(Debug, Clone)]
294pub struct SPSInfo {
295    pub num_of_sps: u8,
296    pub sps: Vec<SPS>,
297}
298
299impl SPSInfo {
300    pub fn parse<R>(di: &mut DataReader<R>) -> (u8, SPSInfo)
301    where
302        R: Read + Seek,
303    {
304        let r2 = di.read_u8().unwrap();
305        let reserved_2 = (r2 & 0b11100000) >> 5;
306        let num_of_sps = r2 & 0b00011111;
307        let mut sps = Vec::new();
308        for _ in 0..num_of_sps {
309            let sps_length = di.read_u16().unwrap();
310            let sps_nal_unit = di.read(sps_length as u64).unwrap();
311            sps.push(SPS {
312                sps_length,
313                sps_nal_unit,
314            });
315        }
316        (reserved_2, SPSInfo { num_of_sps, sps })
317    }
318
319    pub fn length(&self) -> u64 {
320        self.sps.iter().map(|p| p.sps_length as u64 + 2).sum()
321    }
322}
323
324impl ConvertBytes for SPSInfo {
325    type T = u8;
326    fn to_bytes(&self) -> Vec<Self::T> {
327        let mut val = vec![self.num_of_sps];
328        for s in &self.sps {
329            val.append(&mut s.to_bytes());
330        }
331        val
332    }
333}
334
335#[derive(Debug, Clone)]
336pub struct PPS {
337    pub pps_length: u16,
338    pub pps_nal_unit: Vec<u8>,
339}
340
341impl ConvertBytes for PPS {
342    type T = u8;
343    fn to_bytes(&self) -> Vec<Self::T> {
344        let mut val = self.pps_length.to_be_bytes().to_vec();
345        val.append(&mut self.pps_nal_unit.clone());
346        val
347    }
348}
349
350#[derive(Debug, Clone)]
351pub struct PPSInfo {
352    pub num_of_pps: u8,
353    pub pps: Vec<PPS>,
354}
355
356impl PPSInfo {
357    pub fn parse<R>(di: &mut DataReader<R>) -> PPSInfo
358    where
359        R: Read + Seek,
360    {
361        let num_of_pps = di.read_u8().unwrap();
362        let mut pps = Vec::new();
363        for _ in 0..num_of_pps {
364            let pps_length = di.read_u16().unwrap();
365            let pps_nal_unit = di.read(pps_length as u64).unwrap();
366            pps.push(PPS {
367                pps_length,
368                pps_nal_unit,
369            });
370        }
371
372        PPSInfo { num_of_pps, pps }
373    }
374
375    pub fn length(&self) -> u64 {
376        self.pps.iter().map(|p| p.pps_length as u64 + 2).sum()
377    }
378}
379
380impl ConvertBytes for PPSInfo {
381    type T = u8;
382    fn to_bytes(&self) -> Vec<Self::T> {
383        let mut val = vec![self.num_of_pps];
384        for p in &self.pps {
385            val.append(&mut p.to_bytes());
386        }
387        val
388    }
389}
390
391#[derive(Debug, Clone)]
392pub struct AVCDecoderConfigurationRecord {
393    configuration_version: u8,
394    avc_profile_indication: u8,
395    profile_compatibility: u8,
396    avc_level_indication: u8,
397    reserved_1: u8,
398    length_size_minus_one: u8,
399    reserved_2: u8,
400    sps_info: SPSInfo,
401    pps_info: PPSInfo,
402    other_data: Vec<u8>,
403}
404
405impl AVCDecoderConfigurationRecord {
406    pub fn parse<R>(di: &mut DataReader<R>, tag_header: &TagHeader) -> AVCDecoderConfigurationRecord
407    where
408        R: Read + Seek,
409    {
410        let configuration_version = di.read_u8().unwrap();
411        let avc_profile_indication = di.read_u8().unwrap();
412        let profile_compatibility = di.read_u8().unwrap();
413        let avc_level_indication = di.read_u8().unwrap();
414        let r1 = di.read_u8().unwrap();
415        let reserved_1 = (r1 & 0b11111100) >> 2;
416        let length_size_minus_one = r1 & 0b00000011;
417        let (reserved_2, sps_info) = SPSInfo::parse(di);
418        let pps_info = PPSInfo::parse(di);
419        let other_data_len =
420            tag_header.data_size as u64 - 12 - sps_info.length() - pps_info.length();
421        let other_data = match other_data_len {
422            l if l > 0 => di.read(l).unwrap(),
423            _ => Vec::new(),
424        };
425        AVCDecoderConfigurationRecord {
426            configuration_version,
427            avc_profile_indication,
428            profile_compatibility,
429            avc_level_indication,
430            reserved_1,
431            length_size_minus_one,
432            reserved_2,
433            sps_info,
434            pps_info,
435            other_data,
436        }
437    }
438}
439
440impl ConvertBytes for AVCDecoderConfigurationRecord {
441    type T = u8;
442    fn to_bytes(&self) -> Vec<Self::T> {
443        let mut val = vec![
444            self.configuration_version,
445            self.avc_profile_indication,
446            self.profile_compatibility,
447            self.avc_profile_indication,
448            ((self.reserved_1 & 0b111111) << 2) | (self.length_size_minus_one & 0b11),
449        ];
450        let mut sps_bytes = self.sps_info.to_bytes();
451        sps_bytes[0] = ((self.reserved_2 << 5) & 0b11100000)  | (sps_bytes[0] & 0b00011111);
452        val.append(&mut sps_bytes);
453        val.append(&mut self.pps_info.to_bytes());
454        val.append(&mut self.other_data.clone());
455
456        val
457    }
458}
459
460#[derive(Debug, Clone)]
461pub struct AudioSpecificConfig {
462    audio_object_type: u8,
463    sampling_frequency_index: u8,
464    channel_configuration: u8,
465    other: u8,
466    other_data: Vec<u8>,
467}
468
469impl ConvertBytes for AudioSpecificConfig {
470    type T = u8;
471    fn to_bytes(&self) -> Vec<Self::T> {
472        let pre2byte = (self.audio_object_type as u16) << 11
473            | (self.sampling_frequency_index as u16) << 7
474            | (self.channel_configuration as u16) << 3
475            | (self.other as u16);
476        let mut val = pre2byte.to_be_bytes().to_vec();
477        val.append(&mut self.other_data.clone());
478        val
479    }
480}
481
482#[derive(Debug, Clone)]
483pub struct VideoData {
484    pub frame_type: u8,
485    pub codec_id: u8,
486    pub avc_package_type: u8,
487    pub composition_time_offset: u32,
488    pub data: Vec<u8>,
489    pub avc_decoder_configuration_record: Option<AVCDecoderConfigurationRecord>,
490}
491
492impl ConvertBytes for VideoData {
493    type T = u8;
494    fn to_bytes(&self) -> Vec<Self::T> {
495        let first_byte = self.frame_type << 4 | self.codec_id;
496        let mut val = vec![first_byte, self.avc_package_type];
497        val.append(&mut self.composition_time_offset.to_be_bytes()[1..].to_vec());
498        let mut body_data = match self.avc_package_type {
499            FLV_AVC_PACKAGE_TYPE_AVC_SEQUENCE_HEADER => {
500                self.avc_decoder_configuration_record.as_ref().unwrap().to_bytes()
501            }
502            _ => self.data.clone(),
503        };
504        val.append(&mut body_data);
505        val
506    }
507}
508
509#[derive(Debug, Clone)]
510pub struct AudioData {
511    pub sound_format: u8,
512    pub sound_rate: u8,
513    pub sound_size: u8,
514    pub sound_type: u8,
515    pub aac_package_type: Option<u8>,
516    pub audio_specific_config: Option<AudioSpecificConfig>,
517    data: Vec<u8>,
518}
519
520impl ConvertBytes for AudioData {
521    type T = u8;
522
523    fn to_bytes(&self) -> Vec<Self::T> {
524        let first_byte = ((self.sound_format << 4) & 0xF0)
525            | ((self.sound_rate << 2) & 0xC)
526            | ((self.sound_size << 1) & 0x2)
527            | (self.sound_type & 0x1);
528        let mut val = vec![first_byte];
529        let mut body_data = match self.sound_format {
530            FLV_AUDIO_SOUND_FORMAT_AAC => match self.aac_package_type {
531                Some(FLV_AAC_PACKET_TYPE_AAC_SEQUENCE_HEADER) => {
532                    let mut aac_body_data = vec![FLV_AAC_PACKET_TYPE_AAC_SEQUENCE_HEADER];
533                    aac_body_data.append(&mut self.audio_specific_config.as_ref().unwrap().to_bytes());
534                    aac_body_data
535                },
536                Some(_) => {
537                    let mut aac_body_data = vec![FLV_AAC_PACKET_TYPE_AAC_RAW];
538                    aac_body_data.append(&mut self.data.clone());
539                    aac_body_data
540                },
541                None => Vec::new(),
542            },
543            _ => self.data.clone(),
544        };
545        val.append(&mut body_data);
546        val
547    }
548}
549
550#[derive(Debug)]
551pub struct Tag {
552    previous_tag_size: u32,
553    header: TagHeader,
554    video_data: Option<VideoData>,
555    audio_data: Option<AudioData>,
556    metadata: Option<Metadata>,
557}
558
559impl Tag {
560    pub fn is_metadata(&self) -> bool {
561        !matches!(self.metadata, None)
562    }
563
564    pub fn is_avc_decoder_config(&self) -> bool {
565        if self.header.tag_type != FLV_TAG_TYPE_VIDEO {
566            return false;
567        }
568        match &self.video_data {
569            Some(data) => data.avc_package_type == FLV_AVC_PACKAGE_TYPE_AVC_SEQUENCE_HEADER,
570            None => false,
571        }
572    }
573
574    pub fn is_aac_spec_config(&self) -> bool {
575        if self.header.tag_type != FLV_TAG_TYPE_AUDIO {
576            return false;
577        }
578        match &self.audio_data {
579            Some(data) => match data.aac_package_type {
580                None => false,
581                Some(aac_package_type) => {
582                    aac_package_type == FLV_AAC_PACKET_TYPE_AAC_SEQUENCE_HEADER
583                }
584            },
585            None => false,
586        }
587    }
588
589    pub fn size(&self) -> u32 {
590        self.header.data_size + 11
591    }
592
593    pub fn parse<R>(di: &mut DataReader<R>) -> Result<Tag, FLVError>
594    where
595        R: Read + Seek,
596    {
597        let previous_tag_size = di.read_u32().unwrap();
598        trace!("previous_tag_size: {}", previous_tag_size);
599        let tag_type_result = di.read_u8();
600        if tag_type_result.is_err() {
601            match tag_type_result.unwrap_err() {
602                IOError::ReadCompleted(_, _) => return Err(FLVError::Complete),
603                _ => return Err(FLVError::ParseError("parse flv error".to_string())),
604            }
605        }
606        let tag_type = tag_type_result.unwrap();
607        let data_size = di.read_to_u64(3).unwrap() as u32;
608        let timestamp_base = di.read_to_u64(3).unwrap() as u32;
609        let timestamp_extended = di.read_to_u64(1).unwrap() as u32;
610        let stream_id = di.read_to_u64(3).unwrap() as u32;
611        let tag_header = TagHeader {
612            tag_type,
613            data_size,
614            timestamp_base,
615            timestamp_extended,
616            stream_id,
617        };
618        trace!("parse header: {:?}", tag_header);
619        match tag_type {
620            FLV_TAG_TYPE_SCRIPT => Ok(Tag {
621                header: tag_header,
622                metadata: Some(Tag::parse_script(di)),
623                video_data: None,
624                audio_data: None,
625                previous_tag_size,
626            }),
627            FLV_TAG_TYPE_AUDIO => {
628                let audio_data = Tag::parse_audio(di, &tag_header);
629                Ok(Tag {
630                    header: tag_header,
631                    metadata: None,
632                    video_data: None,
633                    audio_data: Some(audio_data),
634                    previous_tag_size,
635                })
636            }
637            FLV_TAG_TYPE_VIDEO => {
638                let video_data = Tag::parse_video(di, &tag_header);
639                Ok(Tag {
640                    header: tag_header,
641                    metadata: None,
642                    video_data: Some(video_data),
643                    audio_data: None,
644                    previous_tag_size,
645                })
646            }
647            _ => Err(FLVError::ParseError(
648                format!("FLV tag type is {}, must be 8, 9, 18", tag_type).to_string(),
649            )),
650        }
651    }
652
653    fn parse_script<R>(di: &mut DataReader<R>) -> Metadata
654    where
655        R: Read + Seek,
656    {
657        let name_data_type = di.read_u8().unwrap();
658        if name_data_type != FLV_SCRIPT_TYPE_STRING {
659            error!("Script Tag AMF1 type error {}", name_data_type);
660            panic!("Script Tag AMF1 type error {}", name_data_type);
661        }
662        let name_data_size = di.read_u16().unwrap();
663        let name = di.read_string(name_data_size as u64).unwrap();
664        if !"onMetaData".eq_ignore_ascii_case(&name) {
665            panic!("Script Tag AMF1 string error: {}", name);
666        }
667        let data_type = di.read_u8().unwrap();
668        if data_type != FLV_SCRIPT_TYPE_ECMA_ARRAY {
669            panic!("Script Tag AMF2 type error: {}", data_type);
670        }
671        let count = di.read_u32().unwrap();
672        let mut data: LinkedHashMap<String, Value> = LinkedHashMap::new();
673        let mut keyframes: Option<Keyframes> = None;
674        for _ in 0..count {
675            match AMF::parse_variable(di) {
676                Ok((k, v)) => {
677                    if k.eq("keyframes") {
678                        keyframes = match v {
679                            Value::Object(v) => {
680                                let times: Vec<f64> = v.get("times").unwrap().try_into().unwrap();
681                                let file_positions: Vec<f64> =
682                                    v.get("filepositions").unwrap().try_into().unwrap();
683                                Some(Keyframes {
684                                    times,
685                                    file_positions,
686                                })
687                            }
688                            _ => None,
689                        }
690                    } else {
691                        data.insert(k, v);
692                    }
693                }
694                Err(_) => continue,
695            }
696        }
697        di.skip(3);
698        Metadata { keyframes, data }
699    }
700
701    fn parse_audio<R>(di: &mut DataReader<R>, tag_header: &TagHeader) -> AudioData
702    where
703        R: Read + Seek,
704    {
705        let sound_info = di.read_u8().unwrap();
706        let sound_format = (sound_info & 0b11110000) >> 4;
707        let sound_rate = (sound_info & 0b00001100) >> 2;
708        let sound_size = (sound_info & 0b00000010) >> 1;
709        let sound_type = sound_info & 0b00000001;
710        let mut aac_package_type: Option<u8> = None;
711        let (audio_spec_config, data): (Option<AudioSpecificConfig>, Vec<u8>) = match sound_format {
712            FLV_AUDIO_SOUND_FORMAT_AAC => {
713                aac_package_type = Some(di.read_u8().unwrap());
714                match aac_package_type {
715                    Some(FLV_AAC_PACKET_TYPE_AAC_SEQUENCE_HEADER) => {
716                        let val = di.read_u16().unwrap();
717                        let audio_object_type = ((val & 0b1111100000000000) >> 11) as u8;
718                        let sampling_frequency_index = ((val & 0b0000011110000000) >> 7) as u8;
719                        let channel_configuration = ((val & 0b0000000001111000) >> 3) as u8;
720                        let other = (val & 0b0000000000000111) as u8;
721                        let other_data = di.read((tag_header.data_size - 4) as u64).unwrap();
722                        (
723                            Some(AudioSpecificConfig {
724                                audio_object_type,
725                                sampling_frequency_index,
726                                channel_configuration,
727                                other,
728                                other_data,
729                            }),
730                            Vec::new(),
731                        )
732                    }
733                    Some(FLV_AAC_PACKET_TYPE_AAC_RAW) => {
734                        (None, di.read((tag_header.data_size - 2) as u64).unwrap())
735                    }
736                    Some(_) => (None, Vec::new()),
737                    None => (None, Vec::new()),
738                }
739            }
740            FLV_AUDIO_SOUND_FORMAT_MP3 => {
741                (None, di.read((tag_header.data_size - 1) as u64).unwrap())
742            }
743            t => panic!("{} not support", t),
744        };
745        AudioData {
746            sound_format,
747            sound_rate,
748            sound_size,
749            sound_type,
750            aac_package_type,
751            audio_specific_config: audio_spec_config,
752            data,
753        }
754    }
755
756    fn parse_video<R>(di: &mut DataReader<R>, tag_header: &TagHeader) -> VideoData
757    where
758        R: Read + Seek,
759    {
760        let val = di.read_u8().unwrap();
761        let frame_type = (val & 0xf0) >> 4;
762        let codec_id = val & 0x0f;
763        let avc_package_type = di.read_u8().unwrap();
764        let composition_time_offset = di.read_to_u64(3).unwrap() as u32;
765        let (avc_decoder_configuration_record, data) = match avc_package_type {
766            FLV_AVC_PACKAGE_TYPE_AVC_SEQUENCE_HEADER => (
767                Some(AVCDecoderConfigurationRecord::parse(di, tag_header)),
768                Vec::new(),
769            ),
770            _ => {
771                let limit = tag_header.data_size - 5;
772                let data: Vec<u8>;
773                if limit <= 0 {
774                    data = Vec::new();
775                } else {
776                    data = di.read(limit.into()).unwrap();
777                }
778                (None, data)
779            }
780        };
781
782        VideoData {
783            frame_type,
784            codec_id,
785            avc_package_type,
786            composition_time_offset,
787            avc_decoder_configuration_record,
788            data,
789        }
790    }
791}
792
793impl ConvertBytes for Tag {
794    type T = u8;
795
796    fn to_bytes(&self) -> Vec<Self::T> {
797        let mut val = Vec::new();
798        val.append(&mut self.previous_tag_size.to_be_bytes().to_vec());
799        val.append(&mut self.header.to_bytes());
800        val.append(&mut (match self.header.tag_type {
801            FLV_TAG_TYPE_SCRIPT => self.metadata.as_ref().unwrap().to_bytes(),
802            FLV_TAG_TYPE_VIDEO => self.video_data.as_ref().unwrap().to_bytes(),
803            FLV_TAG_TYPE_AUDIO => self.audio_data.as_ref().unwrap().to_bytes(),
804            _ => panic!("tag type {} not supported", self.header.tag_type),
805        }));
806        val
807    }
808    
809}
810
811#[derive(Debug)]
812pub struct Header {
813    pub signature: String,
814    pub version: u8,
815    pub type_flags_audio: bool,
816    pub type_flags_video: bool,
817    pub size: u32,
818}
819
820impl Header {
821    pub fn parse<R>(di: &mut DataReader<R>) -> Header
822    where
823        R: Read + Seek,
824    {
825        let data = di.read(9).unwrap();
826        Header {
827            signature: String::from_utf8(data[..3].to_vec()).unwrap(),
828            version: data[3],
829            type_flags_audio: (data[4] & 0b00000100) >> 2 == 1,
830            type_flags_video: (data[4] & 0b00000001) == 1,
831            size: u32::from_be_bytes(data[5..9].to_vec().try_into().unwrap()),
832        }
833    }
834
835    pub fn has_video(&self) -> bool {
836        self.type_flags_video
837    }
838    pub fn has_audio(&self) -> bool {
839        self.type_flags_audio
840    }
841    pub fn to_bytes(&self) -> Vec<u8> {
842        let mut bytes = Vec::new();
843        let mut signature_bytes = self.signature.clone().into_bytes();
844        bytes.append(&mut signature_bytes);
845        bytes.push(self.version);
846        let mut type_flags = 0u8;
847        type_flags = match self.type_flags_audio {
848            true => type_flags | 0b00000100,
849            false => type_flags | 0,
850        };
851        type_flags = match self.type_flags_video {
852            true => type_flags | 0b00000101,
853            false => type_flags | 0b00000100,
854        };
855        bytes.push(type_flags);
856        bytes.append(&mut self.size.to_be_bytes().to_vec());
857
858        bytes
859    }
860}
861
862#[derive(Debug)]
863pub struct Body {
864    metadata_idx: usize,
865    avc_decoder_config_idx: usize,
866    aac_spec_config_idx: Option<usize>,
867    pub tags: Vec<Tag>,
868}
869
870impl Body {
871    pub fn parse<R>(di: &mut DataReader<R>) -> Body
872    where
873        R: Read + Seek,
874    {
875        let mut tags: Vec<Tag> = Vec::new();
876        let mut idx = 0usize;
877        let mut metadata_idx = 0usize;
878        let mut avc_decoder_config_idx = 0usize;
879        let mut aac_spec_config_idx = None;
880        loop {
881            let di_ = &mut *di;
882            let tag_result = Tag::parse(di_);
883            match tag_result {
884                Ok(tag) => {
885                    if tag.is_metadata() {
886                        metadata_idx = idx;
887                    } else if tag.is_avc_decoder_config() {
888                        avc_decoder_config_idx = idx;
889                    } else if tag.is_aac_spec_config() {
890                        aac_spec_config_idx = Some(idx);
891                    }
892                    tags.push(tag);
893                }
894                Err(FLVError::Complete) => break,
895                Err(e) => {
896                    error!("parse body error: {}", e);
897                    panic!("{:?}", e)
898                },
899            }
900            idx += 1;
901        }
902        Body {
903            metadata_idx,
904            avc_decoder_config_idx,
905            aac_spec_config_idx,
906            tags,
907        }
908    }
909
910    pub fn metadata(&self) -> &Tag {
911        &self.tags[self.metadata_idx]
912    }
913
914    pub fn avc_decoder_config(&self) -> &Tag {
915        &self.tags[self.avc_decoder_config_idx]
916    }
917
918    pub fn aac_spec_config(&self) -> Option<&Tag> {
919        match self.aac_spec_config_idx {
920            Some(idx) => Some(&self.tags[idx]),
921            None => None,
922        }
923    }
924}
925
926#[derive(Debug)]
927pub struct FLV {
928    pub header: Header,
929    pub body: Body,
930}
931
932impl FLV {
933    pub fn open(file_path: &str) -> Result<FLV, FLVError> {
934        debug!("start read file:{}", file_path);
935        let file = File::open(file_path);
936        if file.is_err() {
937            return Err(FLVError::ParseError(format!("{}", file.unwrap_err())));
938        }
939        let mut data_reader = DataReader::open(file.unwrap());
940        let header = Header::parse(&mut data_reader);
941        trace!("parse header: {:?}", header);
942        let body = Body::parse(&mut data_reader);
943        debug!("end read file:{}", file_path);
944        Ok(FLV { header, body })
945    }
946
947    pub fn open_with_reader<R: Read + Seek>(reader: &mut R) -> Result<FLV, FLVError> {
948        let mut data_reader = DataReader::open(reader);
949        let header = Header::parse(&mut data_reader);
950        debug!("parse header: {:?}", header);
951        let body = Body::parse(&mut data_reader);
952        Ok(FLV { header, body })
953    }
954
955    pub fn write_file(&mut self, file_path: &str) -> Result<u8, FLVError> {
956        let mut file = File::create(file_path).unwrap();
957        self.write(&mut file)
958    }
959
960    pub fn write<F: Write + Seek>(&mut self, f: &mut F) -> Result<u8, FLVError> {
961        f.write(self.header.to_bytes().as_slice()).unwrap();
962        for tag in &self.body.tags {
963            f.write(tag.to_bytes().as_slice()).unwrap();
964        }
965        let last_tag = &self.body.tags[self.body.tags.len() - 1];
966        f.write(&last_tag.size().to_be_bytes().to_vec()).unwrap();
967        Ok(0)
968    }
969}