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;
78pub(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#[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}