正在显示
1 个修改的文件
包含
9 行增加
和
185 行删除
| @@ -1958,152 +1958,6 @@ public: | @@ -1958,152 +1958,6 @@ public: | ||
| 1958 | } | 1958 | } |
| 1959 | }; | 1959 | }; |
| 1960 | 1960 | ||
| 1961 | -class FlvMuxer | ||
| 1962 | -{ | ||
| 1963 | -public: | ||
| 1964 | - int fd; | ||
| 1965 | - const char* file; | ||
| 1966 | - bool audio_sequence_header_writen; | ||
| 1967 | - | ||
| 1968 | - FlvMuxer() | ||
| 1969 | - { | ||
| 1970 | - file = NULL; | ||
| 1971 | - fd = 0; | ||
| 1972 | - audio_sequence_header_writen = false; | ||
| 1973 | - } | ||
| 1974 | - | ||
| 1975 | - virtual ~FlvMuxer() | ||
| 1976 | - { | ||
| 1977 | - if (fd > 0) { | ||
| 1978 | - close(fd); | ||
| 1979 | - } | ||
| 1980 | - } | ||
| 1981 | - | ||
| 1982 | - int open(const char* _file) | ||
| 1983 | - { | ||
| 1984 | - file = _file; | ||
| 1985 | - if ((fd = ::open(file, O_CREAT|O_WRONLY|O_TRUNC, | ||
| 1986 | - S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH)) < 0 | ||
| 1987 | - ) { | ||
| 1988 | - return -1; | ||
| 1989 | - } | ||
| 1990 | - | ||
| 1991 | - char header[] = { | ||
| 1992 | - 0x46, 0x4c, 0x56, // FLV | ||
| 1993 | - 0x01, // version: 01 | ||
| 1994 | - 0x04, // 0x05:audio+video, 0x01:video, 0x04:audio | ||
| 1995 | - 0x00, 0x00, 0x00, 0x09, // offset: always 0x09 | ||
| 1996 | - 0x00, 0x00, 0x00, 0x00 // previous tag 0: always 0 | ||
| 1997 | - }; | ||
| 1998 | - if (write(fd, header, sizeof(header)) != sizeof(header)) { | ||
| 1999 | - return -1; | ||
| 2000 | - } | ||
| 2001 | - | ||
| 2002 | - return 0; | ||
| 2003 | - } | ||
| 2004 | - | ||
| 2005 | - /** | ||
| 2006 | - * @param size, if 0 for sequence header. | ||
| 2007 | - * @param sound_rate, Sampling rate. The following values are defined: | ||
| 2008 | - * 0 = 5.5 kHz | ||
| 2009 | - * 1 = 11 kHz | ||
| 2010 | - * 2 = 22 kHz | ||
| 2011 | - * 3 = 44 kHz | ||
| 2012 | - * @param sound_type, Mono or stereo sound | ||
| 2013 | - * 0 = Mono sound | ||
| 2014 | - * 1 = Stereo sound | ||
| 2015 | - */ | ||
| 2016 | - int write_audio(char* data, int size, u_int32_t timestamp, int sound_rate, int sound_type) | ||
| 2017 | - { | ||
| 2018 | - if (size > 0 && !audio_sequence_header_writen) { | ||
| 2019 | - audio_sequence_header_writen = true; | ||
| 2020 | - if (write_audio(NULL, 0, 0, sound_rate, sound_type) != 0) { | ||
| 2021 | - return -1; | ||
| 2022 | - } | ||
| 2023 | - } | ||
| 2024 | - | ||
| 2025 | - char tag_header[11]; | ||
| 2026 | - char sequence_header[2]; // aac only | ||
| 2027 | - | ||
| 2028 | - int data_size = size + sizeof(sequence_header); | ||
| 2029 | - int tag_size = data_size + sizeof(tag_header); | ||
| 2030 | - | ||
| 2031 | - //////////////////////////////////// | ||
| 2032 | - // 11bytes tag header. | ||
| 2033 | - //////////////////////////////////// | ||
| 2034 | - // TagType | ||
| 2035 | - char* p = tag_header; | ||
| 2036 | - *p++ = 0x08; // audio | ||
| 2037 | - | ||
| 2038 | - // DataSize | ||
| 2039 | - char* pp = (char*)&data_size; | ||
| 2040 | - *p++ = pp[2]; | ||
| 2041 | - *p++ = pp[1]; | ||
| 2042 | - *p++ = pp[0]; | ||
| 2043 | - | ||
| 2044 | - // Timestamp | ||
| 2045 | - pp = (char*)×tamp; | ||
| 2046 | - *p++ = pp[2]; | ||
| 2047 | - *p++ = pp[1]; | ||
| 2048 | - *p++ = pp[0]; | ||
| 2049 | - | ||
| 2050 | - // TimestampExtended | ||
| 2051 | - *p++ = pp[3]; | ||
| 2052 | - | ||
| 2053 | - //StreamID | ||
| 2054 | - *p++ = 0; | ||
| 2055 | - *p++ = 0; | ||
| 2056 | - *p++ = 0; | ||
| 2057 | - | ||
| 2058 | - //////////////////////////////////// | ||
| 2059 | - // 2bytes codec header for aac | ||
| 2060 | - //////////////////////////////////// | ||
| 2061 | - // SoundFormat | ||
| 2062 | - sequence_header[0] = 0xa0; // aac | ||
| 2063 | - sequence_header[0] |= (sound_rate << 2) & 0x0c; | ||
| 2064 | - sequence_header[0] |= 0x02; // Compressed formats always decode to 16 bits internally. | ||
| 2065 | - sequence_header[0] |= sound_type & 0x01; | ||
| 2066 | - // AACPacketType | ||
| 2067 | - if (size == 0) { | ||
| 2068 | - sequence_header[1] = 0x00; | ||
| 2069 | - } else { | ||
| 2070 | - sequence_header[1] = 0x01; | ||
| 2071 | - } | ||
| 2072 | - | ||
| 2073 | - //////////////////////////////////// | ||
| 2074 | - // 4bytes tag size | ||
| 2075 | - //////////////////////////////////// | ||
| 2076 | - char tag_size_bytes[4]; | ||
| 2077 | - p = tag_size_bytes; | ||
| 2078 | - pp = (char*)&tag_size; | ||
| 2079 | - *p++ = pp[4]; | ||
| 2080 | - *p++ = pp[2]; | ||
| 2081 | - *p++ = pp[1]; | ||
| 2082 | - *p++ = pp[0]; | ||
| 2083 | - | ||
| 2084 | - // write | ||
| 2085 | - if (write(fd, tag_header, sizeof(tag_header)) != sizeof(tag_header)) { | ||
| 2086 | - return -1; | ||
| 2087 | - } | ||
| 2088 | - if (write(fd, sequence_header, sizeof(sequence_header)) != sizeof(sequence_header)) { | ||
| 2089 | - return -1; | ||
| 2090 | - } | ||
| 2091 | - if (size > 0 && write(fd, data, size) != size) { | ||
| 2092 | - return -1; | ||
| 2093 | - } | ||
| 2094 | - if (write(fd, tag_size_bytes, sizeof(tag_size_bytes)) != sizeof(tag_size_bytes)) { | ||
| 2095 | - return -1; | ||
| 2096 | - } | ||
| 2097 | - | ||
| 2098 | - return 0; | ||
| 2099 | - } | ||
| 2100 | - | ||
| 2101 | - int write_video(char* data, int size) | ||
| 2102 | - { | ||
| 2103 | - return 0; | ||
| 2104 | - } | ||
| 2105 | -}; | ||
| 2106 | - | ||
| 2107 | class AacMuxer | 1961 | class AacMuxer |
| 2108 | { | 1962 | { |
| 2109 | public: | 1963 | public: |
| @@ -2150,7 +2004,7 @@ public: | @@ -2150,7 +2004,7 @@ public: | ||
| 2150 | } | 2004 | } |
| 2151 | }; | 2005 | }; |
| 2152 | 2006 | ||
| 2153 | -int consume(TSMessage* msg, FlvMuxer* flv, AacMuxer* aac_muxer) | 2007 | +int consume(TSMessage* msg, AacMuxer* aac_muxer) |
| 2154 | { | 2008 | { |
| 2155 | int ret = 0; | 2009 | int ret = 0; |
| 2156 | 2010 | ||
| @@ -2176,35 +2030,7 @@ int consume(TSMessage* msg, FlvMuxer* flv, AacMuxer* aac_muxer) | @@ -2176,35 +2030,7 @@ int consume(TSMessage* msg, FlvMuxer* flv, AacMuxer* aac_muxer) | ||
| 2176 | } | 2030 | } |
| 2177 | trace("ts+aac audio raw data parsed, size: %d, 0x%02x 0x%02x 0x%02x 0x%02x", | 2031 | trace("ts+aac audio raw data parsed, size: %d, 0x%02x 0x%02x 0x%02x 0x%02x", |
| 2178 | aac.size, aac.at(0), aac.at(1), aac.at(2), aac.at(3)); | 2032 | aac.size, aac.at(0), aac.at(1), aac.at(2), aac.at(3)); |
| 2179 | - | ||
| 2180 | - int sound_rate = 0; | ||
| 2181 | - if (aac.sampling_frequency_index == TSAacSampleFrequency22050) { | ||
| 2182 | - sound_rate = 0x02; | ||
| 2183 | - } else if(aac.sampling_frequency_index == TSAacSampleFrequency44100) { | ||
| 2184 | - sound_rate = 0x03; | ||
| 2185 | - } else { | ||
| 2186 | - // 0 = 5.5 kHz | ||
| 2187 | - // 1 = 11 kHz | ||
| 2188 | - // others. | ||
| 2189 | - trace("ts+aac flv donot support sample-rate: %d", aac.sampling_frequency_index); | ||
| 2190 | - return -1; | ||
| 2191 | - } | ||
| 2192 | - | ||
| 2193 | - int sound_type = 0; | ||
| 2194 | - if (aac.channel_configuration == 1) { | ||
| 2195 | - // 0 = Mono sound | ||
| 2196 | - sound_type = 0; | ||
| 2197 | - } else if (aac.channel_configuration == 2) { | ||
| 2198 | - // 1 = Stereo sound | ||
| 2199 | - sound_type = 1; | ||
| 2200 | - } else { | ||
| 2201 | - trace("ts+aac flv donot support channel: %d", aac.channel_configuration); | ||
| 2202 | - return -1; | ||
| 2203 | - } | ||
| 2204 | - | ||
| 2205 | - if (flv && (ret = flv->write_audio((char*)aac.raw_data, aac.size, msg->pts, sound_rate, sound_type)) != 0) { | ||
| 2206 | - return ret; | ||
| 2207 | - } | 2033 | + // TODO: process audio. |
| 2208 | } | 2034 | } |
| 2209 | } else { | 2035 | } else { |
| 2210 | // parse H264 video. | 2036 | // parse H264 video. |
| @@ -2222,21 +2048,19 @@ int consume(TSMessage* msg, FlvMuxer* flv, AacMuxer* aac_muxer) | @@ -2222,21 +2048,19 @@ int consume(TSMessage* msg, FlvMuxer* flv, AacMuxer* aac_muxer) | ||
| 2222 | return ret; | 2048 | return ret; |
| 2223 | } | 2049 | } |
| 2224 | 2050 | ||
| 2225 | -int main(int /*argc*/, char** /*argv*/) | 2051 | +int main(int argc, char** argv) |
| 2226 | { | 2052 | { |
| 2227 | const char* file = "livestream-1347.ts"; | 2053 | const char* file = "livestream-1347.ts"; |
| 2228 | - const char* output_flv_file = "livestream.flv"; | ||
| 2229 | - const char* output_aac_file = "livestream.aac"; | 2054 | + const char* output_aac_file = "output.aac"; |
| 2055 | + if (argc > 2) { | ||
| 2056 | + file = argv[1]; | ||
| 2057 | + output_aac_file = argv[2]; | ||
| 2058 | + } | ||
| 2230 | 2059 | ||
| 2231 | int fd = open(file, O_RDONLY); | 2060 | int fd = open(file, O_RDONLY); |
| 2232 | - FlvMuxer flv; | ||
| 2233 | AacMuxer aac_muxer; | 2061 | AacMuxer aac_muxer; |
| 2234 | 2062 | ||
| 2235 | int ret = 0; | 2063 | int ret = 0; |
| 2236 | - if ((ret = flv.open(output_flv_file)) != 0) { | ||
| 2237 | - trace("flv+open open flv file failed."); | ||
| 2238 | - return ret; | ||
| 2239 | - } | ||
| 2240 | if ((ret = aac_muxer.open(output_aac_file)) != 0) { | 2064 | if ((ret = aac_muxer.open(output_aac_file)) != 0) { |
| 2241 | trace("aac_muxer+open open flv file failed."); | 2065 | trace("aac_muxer+open open flv file failed."); |
| 2242 | return ret; | 2066 | return ret; |
| @@ -2280,7 +2104,7 @@ int main(int /*argc*/, char** /*argv*/) | @@ -2280,7 +2104,7 @@ int main(int /*argc*/, char** /*argv*/) | ||
| 2280 | continue; | 2104 | continue; |
| 2281 | } | 2105 | } |
| 2282 | 2106 | ||
| 2283 | - if ((ret = consume(msg, &flv, &aac_muxer)) != 0) { | 2107 | + if ((ret = consume(msg, &aac_muxer)) != 0) { |
| 2284 | trace("demuxer+consume parse and consume message failed. ret=%d", ret); | 2108 | trace("demuxer+consume parse and consume message failed. ret=%d", ret); |
| 2285 | break; | 2109 | break; |
| 2286 | } | 2110 | } |
-
请 注册 或 登录 后发表评论