]> git.sesse.net Git - casparcg/blob - modules/ffmpeg/producer/format/flv.cpp
3a4b4c27d3ab06b0d4c8445e4fc1bcdd8d5bbd38
[casparcg] / modules / ffmpeg / producer / format / flv.cpp
1 #include "../../stdafx.h"\r
2 \r
3 #include "flv.h"\r
4 \r
5 #include <common/exception/exceptions.h>\r
6 \r
7 #include <boost/filesystem.hpp>\r
8 \r
9 #include <iostream>\r
10 \r
11 #include <unordered_map>\r
12 \r
13 namespace caspar {\r
14         \r
15 double to_double(std::vector<char> bytes, bool readInReverse)\r
16 {\r
17     if(bytes.size() != 8)\r
18                 BOOST_THROW_EXCEPTION(caspar_exception());\r
19 \r
20     if (readInReverse)\r
21                 std::reverse(bytes.begin(), bytes.end());\r
22         \r
23         static_assert(sizeof(double) == 8, "");\r
24 \r
25         double* tmp = (double*)bytes.data();\r
26         \r
27         double val = *tmp;\r
28     return val;\r
29 }\r
30 \r
31 double next_double(std::fstream& fileStream)\r
32 {\r
33         std::vector<char> bytes(8);\r
34     fileStream.read(bytes.data(), bytes.size());\r
35         fileStream.seekg(1, std::ios::cur);\r
36     return to_double(bytes, true);\r
37\r
38 \r
39 bool next_bool(std::fstream& fileStream)\r
40 {\r
41         std::vector<char> bytes(1);\r
42     fileStream.read(bytes.data(), bytes.size());\r
43         fileStream.seekg(1, std::ios::cur);\r
44     return bytes[0] != 0;\r
45 }\r
46 \r
47 std::string next_string(std::fstream& fileStream)\r
48 {\r
49         std::vector<char> bytes(256, 0);\r
50         fileStream.seekg(2, std::ios::cur);\r
51     fileStream.getline(bytes.data(), bytes.size(), 0);\r
52     return std::string(bytes.begin(), bytes.end());\r
53 }\r
54 \r
55 std::map<std::string, std::string> read_flv_meta_info(const std::string& filename)\r
56 {\r
57         std::map<std::string, std::string>  values;\r
58 \r
59         if(boost::filesystem2::path(filename).extension() != ".flv")\r
60                 return values;\r
61         \r
62         try\r
63         {\r
64                 if(!boost::filesystem2::exists(filename))\r
65                         BOOST_THROW_EXCEPTION(caspar_exception());\r
66         \r
67                 std::fstream fileStream = std::fstream(filename, std::fstream::in);\r
68                 fileStream.seekg(27, std::ios::beg);\r
69         \r
70                 std::vector<char> bytes(10);\r
71                 fileStream.read(bytes.data(), bytes.size());\r
72                 \r
73                 if(std::string(bytes.begin(), bytes.end()) == "onMetaData")\r
74                 {\r
75                         fileStream.seekg(6, std::ios::cur);\r
76 \r
77                         for(int n = 0; n < 16; ++n)\r
78                         {\r
79                                 char name_size = 0;\r
80                                 fileStream.read(&name_size, 1);\r
81 \r
82                                 if(name_size == 0)\r
83                                         break;\r
84 \r
85                                 std::vector<char> name(name_size);\r
86                                 fileStream.read(name.data(), name.size());\r
87                                 auto name_str = std::string(name.begin(), name.end());\r
88 \r
89                                 char data_type = 0;\r
90                                 fileStream.read(&data_type, 1);\r
91 \r
92                                 switch(data_type)\r
93                                 {\r
94                                 case 0:\r
95                                         values[name_str] = boost::lexical_cast<std::string>(next_double(fileStream));\r
96                                         break;\r
97                                 case 1:\r
98                                         values[name_str] = boost::lexical_cast<std::string>(next_bool(fileStream));\r
99                                         break;\r
100                                 case 2:\r
101                                         values[name_str] = next_string(fileStream);\r
102                                         break;\r
103                                 }\r
104                         }\r
105                 }\r
106         }\r
107         catch(...)\r
108         {\r
109                 CASPAR_LOG_CURRENT_EXCEPTION();\r
110         }\r
111 \r
112     return values;\r
113 }\r
114 \r
115 }