xref: /xiu/protocol/rtmp/src/cache/metadata.rs (revision ccd9a1fa)
1 use {
2     super::errors::MetadataError,
3     crate::amf0::{amf0_reader::Amf0Reader, amf0_writer::Amf0Writer, Amf0ValueType},
4     bytes::BytesMut,
5     bytesio::{bytes_reader::BytesReader, bytes_writer::BytesWriter},
6 };
7 #[derive(Clone)]
8 pub struct MetaData {
9     chunk_body: BytesMut,
10     // values: Vec<Amf0ValueType>,
11 }
12 
13 impl Default for MetaData {
14     fn default() -> Self {
15         Self::new()
16     }
17 }
18 
19 impl MetaData {
20     pub fn new() -> Self {
21         Self {
22             chunk_body: BytesMut::new(),
23             //values: Vec::new(),
24         }
25     }
26     //, values: Vec<Amf0ValueType>
27     pub fn save(&mut self, body: BytesMut) {
28         if self.is_metadata(body.clone()) {
29             self.chunk_body = body;
30         }
31     }
32 
33     //used for the http-flv protocol
34     pub fn remove_set_data_frame(&mut self) -> Result<BytesMut, MetadataError> {
35         let mut amf_writer: Amf0Writer = Amf0Writer::new(BytesWriter::new());
36         amf_writer.write_string(&String::from("@setDataFrame"))?;
37 
38         let (_, right) = self.chunk_body.split_at(amf_writer.len());
39 
40         Ok(BytesMut::from(right))
41     }
42 
43     pub fn is_metadata(&mut self, body: BytesMut) -> bool {
44         let reader = BytesReader::new(body);
45         let result = Amf0Reader::new(reader).read_all();
46 
47         let mut values: Vec<Amf0ValueType> = Vec::new();
48 
49         match result {
50             Ok(v) => {
51                 values.extend_from_slice(&v[..]);
52             }
53             Err(_) => return false,
54         }
55 
56         if values.len() < 2 {
57             return false;
58         }
59 
60         log::info!("metadata: {:?}",values);
61 
62         match values.remove(0) {
63             Amf0ValueType::UTF8String(str) => {
64                 if str != "@setDataFrame" {
65                     return false;
66                 }
67             }
68             _ => {
69                 return false;
70             }
71         }
72 
73         match values.remove(0) {
74             Amf0ValueType::UTF8String(str) => {
75                 if str != "onMetaData" {
76                     return false;
77                 }
78             }
79             _ => {
80                 return false;
81             }
82         }
83 
84         true
85     }
86 
87     pub fn get_chunk_body(&self) -> BytesMut {
88         self.chunk_body.clone()
89     }
90 }
91