我正在努力在nginx rtmp服务器上发布视频。在我的nginx配置中,我有以下几行:
rtmp {
server {
access_log /var/log/nginx/rtmp-access-streaming.log;
listen 1935;
# wait_key on;
wait_video on;
chunk_size 4096;
application live {
live on;
allow publish all;
# deny publish all;
allow play all;
record off;
}
# video on demand for flv files
application vod {
play /home/ulterior/Record;
}
}
到目前为止,视频点播工作还可以,问题是发布实时流。
我用以下代码连接librtmp:
char *rtmp_output = NULL;
const char *rtmp_url = "rtmp://127.0.0.1/live/streamName flashver=FMLE/3.0\20(compatible;\20FMSc/1.0)";
if (rtmp_url) {
rtmp_output = malloc( strlen( rtmp_url )+1 );
strncpy( rtmp_output, rtmp_url, strlen( rtmp_url ));
rtmp_output[ strlen( rtmp_url ) ] = '\0';
printf( "RTMP output to: %s\n", rtmp_output);
printf( "sizeof rtmp %d bytes\n", sizeof(RTMP) );
hRtmp->rtmp = calloc(1, sizeof(RTMP));
memset(hRtmp->rtmp, 0x00, sizeof(RTMP));
printf("created rtmp %p\n", hRtmp->rtmp );
}
if (hRtmp->rtmp) {
printf("setting rtmp\n" );
RTMP_LogSetLevel(RTMP_LOGWARNING);
RTMP_LogSetCallback(rtmp_log);
RTMP_Init(hRtmp->rtmp);
if (!RTMP_SetupURL(hRtmp->rtmp, rtmp_output)) {
printf("error RTMP_SetupURL\n" );
goto cleanup;
}
hRtmp->rtmp->Link.protocol |= RTMP_FEATURE_WRITE;
if (!RTMP_Connect(hRtmp->rtmp, NULL) ) {
printf("error RTMP_Connect\n" );
goto cleanup;
}
if( !RTMP_ConnectStream(hRtmp->rtmp, 0) ) {
printf("error RTMP_Connect stream\n" );
goto cleanup;
}
RTMPPacket packet={0};
{
uint8_t rtmp_buffer[2048];
memset(&packet,0,sizeof(RTMPPacket));
packet.m_nChannel = 0x04;
packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
packet.m_nTimeStamp = 0;
packet.m_nInfoField2 = hRtmp->rtmp->m_stream_id;
packet.m_hasAbsTimestamp = 0;
packet.m_body =(char *) rtmp_buffer;
char * szTmp=(char *)rtmp_buffer;
packet.m_packetType = RTMP_PACKET_TYPE_INFO;
szTmp=put_byte(szTmp, AMF_STRING );
szTmp=put_amf_string(szTmp, "@setDataFrame" );
szTmp=put_byte(szTmp, AMF_STRING );
szTmp=put_amf_string(szTmp, "onMetaData" );
szTmp=put_byte(szTmp, AMF_OBJECT );
szTmp=put_amf_string( szTmp, "author" );
szTmp=put_byte(szTmp, AMF_STRING );
szTmp=put_amf_string( szTmp, "" );
szTmp=put_amf_string( szTmp, "copyright" );
szTmp=put_byte(szTmp, AMF_STRING );
szTmp=put_amf_string( szTmp, "" );
szTmp=put_amf_string( szTmp, "description" );
szTmp=put_byte(szTmp, AMF_STRING );
szTmp=put_amf_string( szTmp, "" );
szTmp=put_amf_string( szTmp, "keywords" );
szTmp=put_byte(szTmp, AMF_STRING );
szTmp=put_amf_string( szTmp, "" );
szTmp=put_amf_string( szTmp, "rating" );
szTmp=put_byte(szTmp, AMF_STRING );
szTmp=put_amf_string( szTmp, "" );
szTmp=put_amf_string( szTmp, "presetname" );
szTmp=put_byte(szTmp, AMF_STRING );
szTmp=put_amf_string( szTmp, "Custom" );
szTmp=put_amf_string( szTmp, "width" );
szTmp=put_amf_double( szTmp, 640.0 );//p264Param->i_width );
szTmp=put_amf_string( szTmp, "width" );
szTmp=put_amf_double( szTmp, 640.0 );//p264Param->i_width );
szTmp=put_amf_string( szTmp, "height" );
szTmp=put_amf_double( szTmp, 480.0 );//p264Param->i_height );
szTmp=put_amf_string( szTmp, "framerate" );
szTmp=put_amf_double( szTmp, 25.0 );//(double)p264Param->i_fps_num / p264Param->i_fps_den );
szTmp=put_amf_string( szTmp, "videocodecid" );
szTmp=put_byte(szTmp, AMF_STRING );
szTmp=put_amf_string( szTmp, "avc1" );
szTmp=put_amf_string( szTmp, "videodatarate" );
szTmp=put_amf_double( szTmp, 1500.0 );//p264Param->rc.i_bitrate );
szTmp=put_amf_string( szTmp, "avclevel" );
szTmp=put_amf_double( szTmp, 1.0 );//p264Param->i_level_idc );
szTmp=put_amf_string( szTmp, "avcprofile" );
szTmp=put_amf_double( szTmp, 0x42 );
szTmp=put_amf_string( szTmp, "videokeyframe_frequency" );
szTmp=put_amf_double( szTmp, 8.0 );
szTmp=put_amf_string( szTmp, "" );
szTmp=put_byte( szTmp, AMF_OBJECT_END );
packet.m_nBodySize=szTmp-(char *)rtmp_buffer;
printf( "sending %d as header\n", packet.m_nBodySize );
hex_dump_internal( packet.m_body, packet.m_nBodySize );
RTMP_SendPacket(hRtmp->rtmp,&packet,1);
}
这似乎也可以正常工作,没有错误:
rtmp set, sending header
sending 307 as header
00000000 02 00 0d 40 73 65 74 44 61 74 61 46 72 61 6d 65 ...@setDataFrame
00000010 02 00 0a 6f 6e 4d 65 74 61 44 61 74 61 03 00 06 ...onMetaData...
00000020 61 75 74 68 6f 72 02 00 00 00 09 63 6f 70 79 72 author.....copyr
00000030 69 67 68 74 02 00 00 00 0b 64 65 73 63 72 69 70 ight.....descrip
00000040 74 69 6f 6e 02 00 00 00 08 6b 65 79 77 6f 72 64 tion.....keyword
00000050 73 02 00 00 00 06 72 61 74 69 6e 67 02 00 00 00 s.....rating....
00000060 0a 70 72 65 73 65 74 6e 61 6d 65 02 00 06 43 75 .presetname...Cu
00000070 73 74 6f 6d 00 05 77 69 64 74 68 00 40 84 00 00 stom..width.@...
00000080 00 00 00 00 00 05 77 69 64 74 68 00 40 84 00 00 ......width.@...
00000090 00 00 00 00 00 06 68 65 69 67 68 74 00 40 7e 00 ......height.@~.
000000a0 00 00 00 00 00 00 09 66 72 61 6d 65 72 61 74 65 .......framerate
000000b0 00 40 39 00 00 00 00 00 00 00 0c 76 69 64 65 6f [email protected]
000000c0 63 6f 64 65 63 69 64 02 00 04 61 76 63 31 00 0d codecid...avc1..
000000d0 76 69 64 65 6f 64 61 74 61 72 61 74 65 00 40 97 videodatarate.@.
000000e0 70 00 00 00 00 00 00 08 61 76 63 6c 65 76 65 6c p.......avclevel
000000f0 00 3f f0 00 00 00 00 00 00 00 0a 61 76 63 70 72 .?.........avcpr
00000100 6f 66 69 6c 65 00 40 50 80 00 00 00 00 00 00 17 ofile.@P........
00000110 76 69 64 65 6f 6b 65 79 66 72 61 6d 65 5f 66 72 videokeyframe_fr
00000120 65 71 75 65 6e 63 79 00 40 20 00 00 00 00 00 00 equency.@ ......
00000130 00 00 09 ...
RTMPLOG=t
: fd=41708, size=196735
header sent
我正在以NALU格式发送数据,我看到它正在写入服务器,但是同一librtmp无法理解该流:
rtmpdump -r rtmp://127.0.0.1/live/streamName -o test --debug &
[2] 2502
root@a13-OLinuXino:/home/ulterior# RTMPDump v2.4
(c) 2010 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL
DEBUG: Protocol : RTMP
DEBUG: Hostname : 127.0.0.1
DEBUG: Port : 1935
DEBUG: Playpath : streamName
DEBUG: tcUrl : rtmp://127.0.0.1:1935/live
DEBUG: app : live
DEBUG: live : no
DEBUG: timeout : 30 sec
DEBUG: Setting buffer time to: 36000000ms
Connecting ...
DEBUG: RTMP_Connect1, ... connected, handshaking
DEBUG: HandShake: Type Answer : 03
DEBUG: HandShake: Server Uptime : 12857710
DEBUG: HandShake: FMS Version : 0.0.0.0
DEBUG: HandShake: Handshaking finished....
DEBUG: RTMP_Connect1, handshaked
DEBUG2: RTMP_SendPacket: fd=5, size=197
DEBUG2: 0000: 03 00 00 00 00 00 c5 14 00 00 00 00 ............
DEBUG2: 0000: 02 00 07 63 6f 6e 6e 65 63 74 00 3f f0 00 00 00 ...connect.?....
DEBUG2: 0010: 00 00 00 03 00 03 61 70 70 02 00 04 6c 69 76 65 ......app...live
DEBUG2: 0020: 00 08 66 6c 61 73 68 56 65 72 02 00 0e 4c 4e 58 ..flashVer...LNX
DEBUG2: 0030: 20 31 30 2c 30 2c 33 32 2c 31 38 00 05 74 63 55 10,0,32,18..tcU
DEBUG2: 0040: 72 6c 02 00 1a 72 74 6d 70 3a 2f 2f 31 32 37 2e rl...rtmp://127.
DEBUG2: 0050: 30 2e 30 2e 31 3a 31 39 33 35 2f 6c 69 76 65 00 0.0.1:1935/live.
DEBUG2: 0060: 04 66 70 61 64 01 00 00 0c 63 61 70 61 62 69 6c .fpad....capabil
DEBUG2: 0070: 69 74 69 65 73 00 40 2e 00 00 00 00 00 00 00 0b ities.@.........
DEBUG2: 0000: c3 .
DEBUG2: 0000: 61 75 64 69 6f 43 6f 64 65 63 73 00 40 a8 ee 00 audioCodecs.@...
DEBUG2: 0010: 00 00 00 00 00 0b 76 69 64 65 6f 43 6f 64 65 63 ......videoCodec
DEBUG2: 0020: 73 00 40 6f 80 00 00 00 00 00 00 0d 76 69 64 65 [email protected]
DEBUG2: 0030: 6f 46 75 6e 63 74 69 6f 6e 00 3f f0 00 00 00 00 oFunction.?.....
DEBUG2: 0040: 00 00 00 00 09 .....
DEBUG: Invoking connect
INFO: Connected...
DEBUG2: RTMP_ReadPacket: fd=5
DEBUG2: 0000: 02 00 00 00 00 00 04 05 00 00 00 00 ............
DEBUG2: 0000: 00 4c 4b 40 .LK@
DEBUG: HandleServerBW: server BW = 5000000
DEBUG2: RTMP_ReadPacket: fd=5
DEBUG2: 0000: 02 00 00 00 00 00 05 06 00 00 00 00 ............
DEBUG2: 0000: 00 4c 4b 40 02 .LK@.
DEBUG: HandleClientBW: client BW = 5000000 2
DEBUG2: RTMP_ReadPacket: fd=5
DEBUG2: 0000: 02 00 00 00 00 00 04 01 00 00 00 00 ............
DEBUG2: 0000: 00 00 10 00 ....
DEBUG: HandleChangeChunkSize, received: chunk size change to 4096
DEBUG2: RTMP_ReadPacket: fd=5
DEBUG2: 0000: 03 00 00 00 00 00 be 14 00 00 00 00 ............
DEBUG2: 0000: 02 00 07 5f 72 65 73 75 6c 74 00 3f f0 00 00 00 ..._result.?....
DEBUG2: 0010: 00 00 00 03 00 06 66 6d 73 56 65 72 02 00 0d 46 ......fmsVer...F
DEBUG2: 0020: 4d 53 2f 33 2c 30 2c 31 2c 31 32 33 00 0c 63 61 MS/3,0,1,123..ca
DEBUG2: 0030: 70 61 62 69 6c 69 74 69 65 73 00 40 3f 00 00 00 pabilities.@?...
DEBUG2: 0040: 00 00 00 00 00 09 03 00 05 6c 65 76 65 6c 02 00 .........level..
DEBUG2: 0050: 06 73 74 61 74 75 73 00 04 63 6f 64 65 02 00 1d .status..code...
DEBUG2: 0060: 4e 65 74 43 6f 6e 6e 65 63 74 69 6f 6e 2e 43 6f NetConnection.Co
DEBUG2: 0070: 6e 6e 65 63 74 2e 53 75 63 63 65 73 73 00 0b 64 nnect.Success..d
DEBUG2: 0080: 65 73 63 72 69 70 74 69 6f 6e 02 00 15 43 6f 6e escription...Con
DEBUG2: 0090: 6e 65 63 74 69 6f 6e 20 73 75 63 63 65 65 64 65 nection succeede
DEBUG2: 00a0: 64 2e 00 0e 6f 62 6a 65 63 74 45 6e 63 6f 64 69 d...objectEncodi
DEBUG2: 00b0: 6e 67 00 00 00 00 00 00 00 00 00 00 00 09 ng............
DEBUG: RTMP_ClientPacket, received: invoke 190 bytes
DEBUG: (object begin)
DEBUG: Property: <Name: no-name., STRING: _result>
DEBUG: Property: <Name: no-name., NUMBER: 1.00>
DEBUG: Property: <Name: no-name., OBJECT>
DEBUG: (object begin)
DEBUG: Property: <Name: fmsVer, STRING: FMS/3,0,1,123>
DEBUG: Property: <Name: capabilities, NUMBER: 31.00>
DEBUG: (object end)
DEBUG: Property: <Name: no-name., OBJECT>
DEBUG: (object begin)
DEBUG: Property: <Name: level, STRING: status>
DEBUG: Property: <Name: code, STRING: NetConnection.Connect.Success>
DEBUG: Property: <Name: description, STRING: Connection succeeded.>
DEBUG: Property: <Name: objectEncoding, NUMBER: 0.00>
DEBUG: (object end)
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking <_result>
DEBUG: HandleInvoke, received result for method call <connect>
DEBUG2: RTMP_SendPacket: fd=5, size=4
DEBUG2: 0000: 02 00 00 00 00 00 04 05 00 00 00 00 ............
DEBUG2: 0000: 00 4c 4b 40 .LK@
DEBUG: sending ctrl. type: 0x0003
DEBUG2: RTMP_SendPacket: fd=5, size=10
DEBUG2: 0000: 42 00 00 00 00 00 0a 04 B.......
DEBUG2: 0000: 00 03 00 00 00 00 00 00 01 2c .........,
DEBUG2: RTMP_SendPacket: fd=5, size=25
DEBUG2: 0000: 43 00 00 00 00 00 19 14 C.......
DEBUG2: 0000: 02 00 0c 63 72 65 61 74 65 53 74 72 65 61 6d 00 ...createStream.
DEBUG2: 0010: 40 00 00 00 00 00 00 00 05 @........
DEBUG: Invoking createStream
DEBUG2: RTMP_ReadPacket: fd=5
DEBUG2: 0000: 03 00 00 00 00 00 1d 14 00 00 00 00 ............
DEBUG2: 0000: 02 00 07 5f 72 65 73 75 6c 74 00 40 00 00 00 00 ..._result.@....
DEBUG2: 0010: 00 00 00 05 00 3f f0 00 00 00 00 00 00 .....?.......
DEBUG: RTMP_ClientPacket, received: invoke 29 bytes
DEBUG: (object begin)
DEBUG: Property: <Name: no-name., STRING: _result>
DEBUG: Property: <Name: no-name., NUMBER: 2.00>
DEBUG: Property: NULL
DEBUG: Property: <Name: no-name., NUMBER: 1.00>
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking <_result>
DEBUG: HandleInvoke, received result for method call <createStream>
DEBUG: SendPlay, seekTime=0, stopTime=0, sending play: streamName
DEBUG2: RTMP_SendPacket: fd=5, size=39
DEBUG2: 0000: 08 00 00 00 00 00 27 14 01 00 00 00 ......'.....
DEBUG2: 0000: 02 00 04 70 6c 61 79 00 40 08 00 00 00 00 00 00 ...play.@.......
DEBUG2: 0010: 05 02 00 0a 73 74 72 65 61 6d 4e 61 6d 65 00 00 ....streamName..
DEBUG2: 0020: 00 00 00 00 00 00 00 .......
DEBUG: Invoking play
DEBUG: sending ctrl. type: 0x0003
DEBUG2: RTMP_SendPacket: fd=5, size=10
DEBUG2: 0000: c2 .
DEBUG2: 0000: 00 03 00 00 00 01 02 25 51 00 .......%Q.
DEBUG2: RTMP_ReadPacket: fd=5
DEBUG2: 0000: 05 00 00 00 00 00 60 14 01 00 00 00 ......`.....
DEBUG2: 0000: 02 00 08 6f 6e 53 74 61 74 75 73 00 00 00 00 00 ...onStatus.....
DEBUG2: 0010: 00 00 00 00 05 03 00 05 6c 65 76 65 6c 02 00 06 ........level...
DEBUG2: 0020: 73 74 61 74 75 73 00 04 63 6f 64 65 02 00 14 4e status..code...N
DEBUG2: 0030: 65 74 53 74 72 65 61 6d 2e 50 6c 61 79 2e 53 74 etStream.Play.St
DEBUG2: 0040: 61 72 74 00 0b 64 65 73 63 72 69 70 74 69 6f 6e art..description
DEBUG2: 0050: 02 00 0a 53 74 61 72 74 20 6c 69 76 65 00 00 09 ...Start live...
DEBUG: RTMP_ClientPacket, received: invoke 96 bytes
DEBUG: (object begin)
DEBUG: Property: <Name: no-name., STRING: onStatus>
DEBUG: Property: <Name: no-name., NUMBER: 0.00>
DEBUG: Property: NULL
DEBUG: Property: <Name: no-name., OBJECT>
DEBUG: (object begin)
DEBUG: Property: <Name: level, STRING: status>
DEBUG: Property: <Name: code, STRING: NetStream.Play.Start>
DEBUG: Property: <Name: description, STRING: Start live>
DEBUG: (object end)
DEBUG: (object end)
DEBUG: HandleInvoke, server invoking <onStatus>
DEBUG: HandleInvoke, onStatus: NetStream.Play.Start
Starting download at: 0.000 kB
DEBUG2: RTMP_ReadPacket: fd=5
DEBUG2: 0000: 05 00 00 00 00 00 18 12 01 00 00 00 ............
DEBUG2: 0000: 02 00 11 7c 52 74 6d 70 53 61 6d 70 6c 65 41 63 ...|RtmpSampleAc
DEBUG2: 0010: 63 65 73 73 01 01 01 01 cess....
DEBUG: RTMP_ClientPacket, received: notify 24 bytes
DEBUG: (object begin)
DEBUG: Property: <Name: no-name., STRING: |RtmpSampleAccess>
DEBUG: Property: <Name: no-name., BOOLEAN: TRUE>
DEBUG: Property: <Name: no-name., BOOLEAN: TRUE>
DEBUG: (object end)
DEBUG2: RTMP_ReadPacket: fd=5
root@a13-OLinuXino:/home/ulterior# DEBUG: RTMPSockBuf_Fill, recv returned -1. GetSockError(): 11 (Resource temporarily unavailable)
ERROR: RTMP_ReadPacket, failed to read RTMP packet header
有人知道这种方法有什么问题吗?我想念什么吗?我发现某种参考,我应该从服务器读回用于ping请求的数据包?欢迎任何帮助。
最佳答案
至于您当前的问题,您使用过吗?
RTMP_EnableWrite(r);