17
17
#define RTMP_RECEIVE_TIMEOUT 2
18
18
#define RTMP_HEAD_SIZE (sizeof (RTMPPacket)+RTMP_MAX_HEADER_SIZE)
19
19
20
+ #define SAVC (x ) static const AVal av_##x = AVC(#x)
21
+
22
+ static const AVal av_setDataFrame = AVC(" @setDataFrame" );
23
+ static const AVal av_SDKVersion = AVC(" LFLiveKit 1.5.2" );
24
+ SAVC (onMetaData);
25
+ SAVC (duration);
26
+ SAVC (width);
27
+ SAVC (height);
28
+ SAVC (videocodecid);
29
+ SAVC (videodatarate);
30
+ SAVC (framerate);
31
+ SAVC (audiocodecid);
32
+ SAVC (audiodatarate);
33
+ SAVC (audiosamplerate);
34
+ SAVC (audiosamplesize);
35
+ SAVC (audiochannels);
36
+ SAVC (stereo);
37
+ SAVC (encoder);
38
+ SAVC (av_stereo);
39
+ SAVC (fileSize);
40
+ SAVC (avc1);
41
+ SAVC (mp4a);
42
+
20
43
@interface LFStreamRtmpSocket ()<LFStreamingBufferDelegate>
21
44
{
22
45
RTMP* _rtmp;
@@ -164,6 +187,8 @@ -(NSInteger) RTMP264_Connect:(char *)push_url{
164
187
[self .delegate socketStatus: self status: LFLiveStart];
165
188
}
166
189
190
+ [self sendMetaData ];
191
+
167
192
_isConnected = YES ;
168
193
_isConnecting = NO ;
169
194
_isReconnecting = NO ;
@@ -182,7 +207,61 @@ -(NSInteger) RTMP264_Connect:(char *)push_url{
182
207
}
183
208
184
209
#pragma mark -- Rtmp Send
185
- - (void )sendVideoHeader : (LFVideoFrame*)videoFrame {
210
+
211
+ - (void )sendMetaData {
212
+ RTMPPacket packet;
213
+
214
+ char pbuf[2048 ], *pend = pbuf+sizeof (pbuf);
215
+
216
+ packet.m_nChannel = 0x03 ; // control channel (invoke)
217
+ packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
218
+ packet.m_packetType = RTMP_PACKET_TYPE_INFO;
219
+ packet.m_nTimeStamp = 0 ;
220
+ packet.m_nInfoField2 = _rtmp->m_stream_id ;
221
+ packet.m_hasAbsTimestamp = TRUE ;
222
+ packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
223
+
224
+ char *enc = packet.m_body ;
225
+ enc = AMF_EncodeString (enc, pend, &av_setDataFrame);
226
+ enc = AMF_EncodeString (enc, pend, &av_onMetaData);
227
+
228
+ *enc++ = AMF_OBJECT;
229
+
230
+ enc = AMF_EncodeNamedNumber (enc, pend, &av_duration, 0.0 );
231
+ enc = AMF_EncodeNamedNumber (enc, pend, &av_fileSize, 0.0 );
232
+
233
+ // videosize
234
+ enc = AMF_EncodeNamedNumber (enc, pend, &av_width, _stream.videoConfiguration .videoSize .width );
235
+ enc = AMF_EncodeNamedNumber (enc, pend, &av_height, _stream.videoConfiguration .videoSize .height );
236
+
237
+ // video
238
+ enc = AMF_EncodeNamedString (enc, pend, &av_videocodecid, &av_avc1);
239
+
240
+ enc = AMF_EncodeNamedNumber (enc, pend, &av_videodatarate, _stream.videoConfiguration .videoBitRate / 1000 .f );
241
+ enc = AMF_EncodeNamedNumber (enc, pend, &av_framerate, _stream.videoConfiguration .videoFrameRate );
242
+
243
+ // audio
244
+ enc = AMF_EncodeNamedString (enc, pend, &av_audiocodecid, &av_mp4a);
245
+ enc = AMF_EncodeNamedNumber (enc, pend, &av_audiodatarate, _stream.audioConfiguration .audioBitrate );
246
+
247
+ enc = AMF_EncodeNamedNumber (enc, pend, &av_audiosamplerate, _stream.audioConfiguration .audioSampleRate );
248
+ enc = AMF_EncodeNamedNumber (enc, pend, &av_audiosamplesize, 16.0 );
249
+ enc = AMF_EncodeNamedBoolean (enc, pend, &av_stereo, _stream.audioConfiguration .numberOfChannels ==2 );
250
+
251
+ // sdk version
252
+ enc = AMF_EncodeNamedString (enc, pend, &av_encoder, &av_SDKVersion);
253
+
254
+ *enc++ = 0 ;
255
+ *enc++ = 0 ;
256
+ *enc++ = AMF_OBJECT_END;
257
+
258
+ packet.m_nBodySize = enc - packet.m_body ;
259
+ if (!RTMP_SendPacket (_rtmp, &packet, FALSE )) {
260
+ return ;
261
+ }
262
+ }
263
+
264
+ - (void )sendVideoHeader : (LFVideoFrame*)videoFrame {
186
265
if (!videoFrame || !videoFrame.sps || !videoFrame.pps ) return ;
187
266
188
267
unsigned char * body=NULL ;
@@ -307,7 +386,7 @@ - (void)sendAudioHeader:(LFAudioFrame*)audioFrame{
307
386
free (body);
308
387
}
309
388
310
- - (void )sendAudio : (LFFrame*)frame {
389
+ - (void )sendAudio : (LFFrame*)frame {
311
390
if (!frame) return ;
312
391
313
392
NSInteger rtmpLength = frame.data .length + 2 ;/* spec data长度,一般是2*/
0 commit comments