RTSP 交互过程
来源:互联网 发布:淘宝买水果靠谱吗 编辑:程序博客网 时间:2024/05/22 08:26
客户端是使用Vlc播放器,以下信息均为服务端收到和回应的信息
第一步:查询服务端可用方法(OPTION)
1客户端请求(OPTION request):---询问服务器有哪些方法可用
"OPTIONS rtsp://192.168.1.122/TestSession RTSP/1.0"
"CSeq: 2"
"User-Agent: LibVLC/1.1.9 (LIVE555 Streaming Media v2011.01.06)"
2 服务器回应(OPTION response):---回复的所有方法在Public字段
"RTSP/1.0 200 OK"
"CSeq: 2"
{"Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE"}
"" //最后这个也很重要,最后一个消息头需要有两个CR LF
第二步:得到媒体描述信息(DESCRIBE)
1 客户端请求(DESCRIBE request):-----要求得到媒体描述信息
"DESCRIBE rtsp://192.168.1.122/TestSession RTSP/1.0"
"CSeq: 3"
"User-Agent: LibVLC/1.1.9 (LIVE555 Streaming Media v2011.01.06)"
"Accept: application/sdp"
2 服务器回应(DESCRIBE response):---回应媒体描述信息,一般是sdp信息
"RTSP/1.0 200 OK"
"CSeq: 3" //和请求的序号要对应
{"Server: RTSP Service"
"Content-Base: rtsp://192.168.1.122/TestSession"
"Content-Type: application/sdp" //表示回应的是sdp信息
"Content-Length: 367"
}
""
然后再发送生成的sdp信息,sdp信息也可以和上面的字符串组合一起发送
第三步:建立RTSP会话(SETUP)
1 客户端请求(SETUP request):-----通过Transport头字段列出可接受的传输选项,建立会话
"SETUP rtsp://192.168.1.122/TestSession/trackID=1 RTSP/1.0"
"CSeq: 4"
"User-Agent: LibVLC/1.1.9 (LIVE555 Streaming Media v2011.01.06)"
"Transport: RTP/AVP;unicast;client_port=2274-2275"
2 服务器回应(SETUP response):--建立会话,通过Transport头字段返回选择的具体传输
选项,并返回建立的Session ID;
"RTSP/1.0 200 OK"
"CSeq: 4"
"Session: 68422540987712"
"Transport:RTP/AVP;unicast;source=192.168.1.122;server_port=8000-8001;client_port=
2274-2275;ssrc=3969838262"
""
第四步:请求开始传送数据(PLAY)
1 客户端请求(PLAY request): -----请求服务器开始发送数据
"PLAY rtsp://192.168.1.122/TestSession RTSP/1.0"
"CSeq: 5"
"User-Agent: LibVLC/1.1.9 (LIVE555 Streaming Media v2011.01.06)"
"Session: 68422540987712"
"Range: npt=0.000-"
2 服务器回应(PLAY response):------回应该请求的信息
"RTSP/1.0 200 OK"
"CSeq: 5"
"Session: 68422540987712"
"RTP-Info: url=rtsp://192.168.1.122/TestSession/trackID=1"
""
第五步:数据传输
服务器->客户端:发送流媒体数据, 通过RTP协议传输数据
第六步:关闭会话,退出(TEARDOWN)
1 客户端请求(TEARDOWN request):---------请求关闭会话
"TEARDOWN rtsp://192.168.1.122/TestSession RTSP/1.0"
"CSeq: 6"
"User-Agent: LibVLC/1.1.9 (LIVE555 Streaming Media v2011.01.06)"
"Session: 68422540987712"
2 服务器回应(TEARDOWN response):
"RTSP/1.0 200 OK"
"CSeq: 6"
"Session: 68422540987712"
"Connection: Close"
""
//---------------------------------华丽分割线----------------------------------------//
备注:此为ODM和设备端之间的RTSP交互日志与上述稍有不同!
04-28 11:52:12.729: I/RTSPServer_jni(741): [live555android.cpp:296 void announceStream(RTSPServer*, ServerMediaSession*, char const*)]: Play this stream using the URL rtsp://192.168.100.102:8554/1
04-28 11:52:48.473: I/RTSPServer_jni(741): [RTSPServer.cpp:431 void RTSPServer::incomingConnectionHandler(int)]: accept()ed connection from 192.168.100.103
04-28 11:52:48.484: I/RTSPServer_jni(741): [RTSPServer.cpp:897 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: RTSPClientConnection[0x5560e858]::handleRequestBytes() read 134 new bytes:DESCRIBE rtsp://192.168.100.102:8554/1 RTSP/1.0
04-28 11:52:48.484: I/RTSPServer_jni(741): CSeq: 2
04-28 11:52:48.484: I/RTSPServer_jni(741): User-Agent: LIVE555 Streaming Media v2012.01.13
04-28 11:52:48.484: I/RTSPServer_jni(741): Accept: application/sdp
04-28 11:52:48.484: I/RTSPServer_jni(741):
04-28 11:52:48.484: I/RTSPServer_jni(741): [RTSPServer.cpp:984 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: parseRTSPRequestString() succeeded, returning cmdName "DESCRIBE", urlPreSuffix "", urlSuffix "1", CSeq "2", Content-Length 0, with 0 bytes following the message.
04-28 11:52:51.995: I/RTSPServer_jni(741): [RTSPServer.cpp:1123 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: sending response: RTSP/1.0 200 OK
04-28 11:52:51.995: I/RTSPServer_jni(741): CSeq: 2
04-28 11:52:51.995: I/RTSPServer_jni(741): Date: Fri, Apr 28 2017 03:52:51 GMT
04-28 11:52:51.995: I/RTSPServer_jni(741): Content-Base: rtsp://192.168.100.102:8554/1/
04-28 11:52:51.995: I/RTSPServer_jni(741): Content-Type: application/sdp
04-28 11:52:51.995: I/RTSPServer_jni(741): Content-Length: 471
04-28 11:52:51.995: I/RTSPServer_jni(741):
04-28 11:52:51.995: I/RTSPServer_jni(741): v=0
04-28 11:52:51.995: I/RTSPServer_jni(741): o=- 1493351532727360 1 IN IP4 192.168.100.102
04-28 11:52:51.995: I/RTSPServer_jni(741): s=Session streamed by "RTSPServer"
04-28 11:52:51.995: I/RTSPServer_jni(741): i=1
04-28 11:52:51.995: I/RTSPServer_jni(741): t=0 0
04-28 11:52:51.995: I/RTSPServer_jni(741): a=tool:LIVE555 Streaming Media v2014.07.18
04-28 11:52:51.995: I/RTSPServer_jni(741): a=type:broadcast
04-28 11:52:51.995: I/RTSPServer_jni(741): a=control:*
04-28 11:52:51.995: I/RTSPServer_jni(741): a=range:npt=0-
04-28 11:52:51.995: I/RTSPServer_jni(741): a=x-qt-text-nam:Session streamed by "RTSPServer"
04-28 11:52:51.995: I/RTSPServer_jni(741): a=x-qt-text-inf:1
04-28 11:52:51.995: I/RTSPServer_jni(741): m=video 0 RTP/AVP 96
04-28 11:52:51.995: I/RTSPServer_jni(741): c=IN IP4 0.0.0.0
04-28 11:52:51.995: I/RTSPServer_jni(741): b=AS:500
04-28 11:52:51.995: I/RTSPServer_jni(741): a=rtpmap:96 H264/90000
04-28 11:52:51.995: I/RTSPServer_jni(741): a=fmtp:96 packetization-mode=1;profile-level-id=42C01E;sprop-parameter-sets=Z0LAHrkQFAe0IAAAAwAgAAAFEeLF1A==,aM48gA==
04-28 11:52:51.995: I/RTSPServer_jni(741): a=control:track1
04-28 11:52:52.086: I/RTSPServer_jni(741): [RTSPServer.cpp:897 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: RTSPClientConnection[0x5560e858]::handleRequestBytes() read 165 new bytes:SETUP rtsp://192.168.100.102:8554/1/track1 RTSP/1.0
04-28 11:52:52.086: I/RTSPServer_jni(741): CSeq: 3
04-28 11:52:52.086: I/RTSPServer_jni(741): User-Agent: LIVE555 Streaming Media v2012.01.13
04-28 11:52:52.086: I/RTSPServer_jni(741): Transport: RTP/AVP;unicast;client_port=53474-53475
04-28 11:52:52.086: I/RTSPServer_jni(741):
04-28 11:52:52.087: I/RTSPServer_jni(741): [RTSPServer.cpp:984 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: parseRTSPRequestString() succeeded, returning cmdName "SETUP", urlPreSuffix "1", urlSuffix "track1", CSeq "3", Content-Length 0, with 0 bytes following the message.
04-28 11:52:52.125: I/RTSPServer_jni(741): [RTSPServer.cpp:1123 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: sending response: RTSP/1.0 200 OK
04-28 11:52:52.125: I/RTSPServer_jni(741): CSeq: 3
04-28 11:52:52.125: I/RTSPServer_jni(741): Date: Fri, Apr 28 2017 03:52:52 GMT
04-28 11:52:52.125: I/RTSPServer_jni(741): Transport: RTP/AVP;unicast;destination=192.168.100.103;source=192.168.100.102;client_port=53474-53475;server_port=6970-6971
04-28 11:52:52.125: I/RTSPServer_jni(741): Session: DB761C12;timeout=65
04-28 11:52:52.125: I/RTSPServer_jni(741):
04-28 11:52:52.160: I/RTSPServer_jni(741): [RTSPServer.cpp:897 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: RTSPClientConnection[0x5560e858]::handleRequestBytes() read 144 new bytes:PLAY rtsp://192.168.100.102:8554/1/ RTSP/1.0
04-28 11:52:52.160: I/RTSPServer_jni(741): CSeq: 4
04-28 11:52:52.160: I/RTSPServer_jni(741): User-Agent: LIVE555 Streaming Media v2012.01.13
04-28 11:52:52.160: I/RTSPServer_jni(741): Session: DB761C12
04-28 11:52:52.160: I/RTSPServer_jni(741): Range: npt=0.000-
04-28 11:52:52.160: I/RTSPServer_jni(741):
04-28 11:52:52.160: I/RTSPServer_jni(741): [RTSPServer.cpp:984 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: parseRTSPRequestString() succeeded, returning cmdName "PLAY", urlPreSuffix "1", urlSuffix "", CSeq "4", Content-Length 0, with 0 bytes following the message.
04-28 11:52:52.162: I/RTSPServer_jni(741): [RTSPServer.cpp:1123 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: sending response: RTSP/1.0 200 OK
04-28 11:52:52.162: I/RTSPServer_jni(741): CSeq: 4
04-28 11:52:52.162: I/RTSPServer_jni(741): Date: Fri, Apr 28 2017 03:52:52 GMT
04-28 11:52:52.162: I/RTSPServer_jni(741): Range: npt=0.000-
04-28 11:52:52.162: I/RTSPServer_jni(741): Session: DB761C12
04-28 11:52:52.162: I/RTSPServer_jni(741): RTP-Info: url=rtsp://192.168.100.102:8554/1/track1;seq=15867;rtptime=2124151534
04-28 11:52:52.162: I/RTSPServer_jni(741):
04-28 11:52:54.227: I/RTSPServer_jni(741): [RTSPServer.cpp:2144 static void RTSPServer::RTSPClientSession::noteClientLiveness(RTSPServer::RTSPClientSession*)]: RTSP client session (id "DB761C12", stream name "1"): Liveness indication
04-28 11:52:57.056: I/RTSPServer_jni(741): [RTSPServer.cpp:2144 static void RTSPServer::RTSPClientSession::noteClientLiveness(RTSPServer::RTSPClientSession*)]: RTSP client session (id "DB761C12", stream name "1"): Liveness indication
04-28 11:53:01.574: I/RTSPServer_jni(741): [RTSPServer.cpp:2144 static void RTSPServer::RTSPClientSession::noteClientLiveness(RTSPServer::RTSPClientSession*)]: RTSP client session (id "DB761C12", stream name "1"): Liveness indication
04-28 11:53:02.490: I/RTSPServer_jni(741): [RTSPServer.cpp:2144 static void RTSPServer::RTSPClientSession::noteClientLiveness(RTSPServer::RTSPClientSession*)]: RTSP client session (id "DB761C12", stream name "1"): Liveness indication
04-28 11:53:02.490: I/RTSPServer_jni(741): [RTSPServer.cpp:897 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: RTSPClientConnection[0x5560e858]::handleRequestBytes() read 129 new bytes:TEARDOWN rtsp://192.168.100.102:8554/1/ RTSP/1.0
04-28 11:53:02.490: I/RTSPServer_jni(741): CSeq: 5
04-28 11:53:02.490: I/RTSPServer_jni(741): User-Agent: LIVE555 Streaming Media v2012.01.13
04-28 11:53:02.490: I/RTSPServer_jni(741): Session: DB761C12
04-28 11:53:02.490: I/RTSPServer_jni(741):
04-28 11:53:02.490: I/RTSPServer_jni(741): [RTSPServer.cpp:984 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: parseRTSPRequestString() succeeded, returning cmdName "TEARDOWN", urlPreSuffix "1", urlSuffix "", CSeq "5", Content-Length 0, with 0 bytes following the message.
04-28 11:53:02.490: I/RTSPServer_jni(741): [RTSPServer.cpp:1123 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: sending response: RTSP/1.0 200 OK
04-28 11:53:02.490: I/RTSPServer_jni(741): CSeq: 5
04-28 11:53:02.490: I/RTSPServer_jni(741): Date: Fri, Apr 28 2017 03:53:02 GMT
04-28 11:53:02.490: I/RTSPServer_jni(741):
04-28 11:53:02.491: I/RTSPServer_jni(741): [RTSPServer.cpp:882 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: RTSPClientConnection[0x5560e858]::handleRequestBytes() read -1 new bytes (of 10000); terminating connection!
04-28 11:53:20.629: I/RTSPServer_jni(741): [RTSPServer.cpp:431 void RTSPServer::incomingConnectionHandler(int)]: accept()ed connection from 192.168.100.103
04-28 11:53:20.636: I/RTSPServer_jni(741): [RTSPServer.cpp:897 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: RTSPClientConnection[0x567cc268]::handleRequestBytes() read 134 new bytes:DESCRIBE rtsp://192.168.100.102:8554/1 RTSP/1.0
04-28 11:53:20.636: I/RTSPServer_jni(741): CSeq: 2
04-28 11:53:20.636: I/RTSPServer_jni(741): User-Agent: LIVE555 Streaming Media v2012.01.13
04-28 11:53:20.636: I/RTSPServer_jni(741): Accept: application/sdp
04-28 11:53:20.636: I/RTSPServer_jni(741):
04-28 11:53:20.636: I/RTSPServer_jni(741): [RTSPServer.cpp:984 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: parseRTSPRequestString() succeeded, returning cmdName "DESCRIBE", urlPreSuffix "", urlSuffix "1", CSeq "2", Content-Length 0, with 0 bytes following the message.
04-28 11:53:20.636: I/RTSPServer_jni(741): [RTSPServer.cpp:1123 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: sending response: RTSP/1.0 200 OK
04-28 11:53:20.636: I/RTSPServer_jni(741): CSeq: 2
04-28 11:53:20.636: I/RTSPServer_jni(741): Date: Fri, Apr 28 2017 03:53:20 GMT
04-28 11:53:20.636: I/RTSPServer_jni(741): Content-Base: rtsp://192.168.100.102:8554/1/
04-28 11:53:20.636: I/RTSPServer_jni(741): Content-Type: application/sdp
04-28 11:53:20.636: I/RTSPServer_jni(741): Content-Length: 471
04-28 11:53:20.636: I/RTSPServer_jni(741):
04-28 11:53:20.636: I/RTSPServer_jni(741): v=0
04-28 11:53:20.636: I/RTSPServer_jni(741): o=- 1493351532727360 1 IN IP4 192.168.100.102
04-28 11:53:20.636: I/RTSPServer_jni(741): s=Session streamed by "RTSPServer"
04-28 11:53:20.636: I/RTSPServer_jni(741): i=1
04-28 11:53:20.636: I/RTSPServer_jni(741): t=0 0
04-28 11:53:20.636: I/RTSPServer_jni(741): a=tool:LIVE555 Streaming Media v2014.07.18
04-28 11:53:20.636: I/RTSPServer_jni(741): a=type:broadcast
04-28 11:53:20.636: I/RTSPServer_jni(741): a=control:*
04-28 11:53:20.636: I/RTSPServer_jni(741): a=range:npt=0-
04-28 11:53:20.636: I/RTSPServer_jni(741): a=x-qt-text-nam:Session streamed by "RTSPServer"
04-28 11:53:20.636: I/RTSPServer_jni(741): a=x-qt-text-inf:1
04-28 11:53:20.636: I/RTSPServer_jni(741): m=video 0 RTP/AVP 96
04-28 11:53:20.636: I/RTSPServer_jni(741): c=IN IP4 0.0.0.0
04-28 11:53:20.636: I/RTSPServer_jni(741): b=AS:500
04-28 11:53:20.636: I/RTSPServer_jni(741): a=rtpmap:96 H264/90000
04-28 11:53:20.636: I/RTSPServer_jni(741): a=fmtp:96 packetization-mode=1;profile-level-id=42C01E;sprop-parameter-sets=Z0LAHrkQFAe0IAAAAwAgAAAFEeLF1A==,aM48gA==
04-28 11:53:20.636: I/RTSPServer_jni(741): a=control:track1
04-28 11:53:20.692: I/RTSPServer_jni(741): [RTSPServer.cpp:897 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: RTSPClientConnection[0x567cc268]::handleRequestBytes() read 165 new bytes:SETUP rtsp://192.168.100.102:8554/1/track1 RTSP/1.0
04-28 11:53:20.692: I/RTSPServer_jni(741): CSeq: 3
04-28 11:53:20.692: I/RTSPServer_jni(741): User-Agent: LIVE555 Streaming Media v2012.01.13
04-28 11:53:20.692: I/RTSPServer_jni(741): Transport: RTP/AVP;unicast;client_port=55586-55587
04-28 11:53:20.692: I/RTSPServer_jni(741):
04-28 11:53:20.692: I/RTSPServer_jni(741): [RTSPServer.cpp:984 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: parseRTSPRequestString() succeeded, returning cmdName "SETUP", urlPreSuffix "1", urlSuffix "track1", CSeq "3", Content-Length 0, with 0 bytes following the message.
04-28 11:53:20.693: I/RTSPServer_jni(741): [RTSPServer.cpp:1123 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: sending response: RTSP/1.0 200 OK
04-28 11:53:20.693: I/RTSPServer_jni(741): CSeq: 3
04-28 11:53:20.693: I/RTSPServer_jni(741): Date: Fri, Apr 28 2017 03:53:20 GMT
04-28 11:53:20.693: I/RTSPServer_jni(741): Transport: RTP/AVP;unicast;destination=192.168.100.103;source=192.168.100.102;client_port=55586-55587;server_port=6970-6971
04-28 11:53:20.693: I/RTSPServer_jni(741): Session: 350E6356;timeout=65
04-28 11:53:20.693: I/RTSPServer_jni(741):
04-28 11:53:20.714: I/RTSPServer_jni(741): [RTSPServer.cpp:897 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: RTSPClientConnection[0x567cc268]::handleRequestBytes() read 144 new bytes:PLAY rtsp://192.168.100.102:8554/1/ RTSP/1.0
04-28 11:53:20.714: I/RTSPServer_jni(741): CSeq: 4
04-28 11:53:20.714: I/RTSPServer_jni(741): User-Agent: LIVE555 Streaming Media v2012.01.13
04-28 11:53:20.714: I/RTSPServer_jni(741): Session: 350E6356
04-28 11:53:20.714: I/RTSPServer_jni(741): Range: npt=0.000-
04-28 11:53:20.714: I/RTSPServer_jni(741):
04-28 11:53:20.714: I/RTSPServer_jni(741): [RTSPServer.cpp:984 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: parseRTSPRequestString() succeeded, returning cmdName "PLAY", urlPreSuffix "1", urlSuffix "", CSeq "4", Content-Length 0, with 0 bytes following the message.
04-28 11:53:20.715: I/RTSPServer_jni(741): [RTSPServer.cpp:1123 void RTSPServer::RTSPClientConnection::handleRequestBytes(int)]: sending response: RTSP/1.0 200 OK
04-28 11:53:20.715: I/RTSPServer_jni(741): CSeq: 4
04-28 11:53:20.715: I/RTSPServer_jni(741): Date: Fri, Apr 28 2017 03:53:20 GMT
04-28 11:53:20.715: I/RTSPServer_jni(741): Range: npt=0.000-
04-28 11:53:20.715: I/RTSPServer_jni(741): Session: 350E6356
04-28 11:53:20.715: I/RTSPServer_jni(741): RTP-Info: url=rtsp://192.168.100.102:8554/1/track1;seq=30273;rtptime=3974772570
04-28 11:53:20.715: I/RTSPServer_jni(741):
04-28 11:53:24.193: I/RTSPServer_jni(741): [RTSPServer.cpp:2144 static void RTSPServer::RTSPClientSession::noteClientLiveness(RTSPServer::RTSPClientSession*)]: RTSP client session (id "350E6356", stream name "1"): Liveness indication
04-28 11:53:28.244: I/RTSPServer_jni(741): [RTSPServer.cpp:2144 static void RTSPServer::RTSPClientSession::noteClientLiveness(RTSPServer::RTSPClientSession*)]: RTSP client session (id "350E6356", stream name "1"): Liveness indication
04-28 11:53:34.027: I/RTSPServer_jni(741): [RTSPServer.cpp:2144 static void RTSPServer::RTSPClientSession::noteClientLiveness(RTSPServer::RTSPClientSession*)]: RTSP client session (id "350E6356", stream name "1"): Liveness indication
04-28 11:53:39.045: I/RTSPServer_jni(741): [RTSPServer.cpp:2144 static void RTSPServer::RTSPClientSession::noteClientLiveness(RTSPServer::RTSPClientSession*)]: RTSP client session (id "350E6356", stream name "1"): Liveness indication
- H264 RTSP交互过程
- H264 RTSP交互过程
- H264 RTSP交互过程
- RTSP协议交互过程
- rtsp交互过程
- RTSP简单交互过程
- RTSP交互过程
- RTSP交互过程
- RTSP 交互过程
- RTSP 协议 简单交互过程
- RTSP 协议 简单交互过程
- 简单的RTSP消息交互过程
- DSS 代码分析【RTSP消息交互过程】
- rtsp交互命令简介及过程参数描述
- rtsp交互命令简介及过程参数描述
- rtsp交互命令简介及过程参数描述
- rtsp交互命令简介及过程参数描述
- rtsp交互命令简介及过程参数描述
- 最大公共子串的长度模板
- 基于MNIST数据集的深度学习库keras的学习
- Android之判断手机连接的网络类型是WIFI还是2G/3G/4G
- NOSQL 数据库分类
- nginx 配置
- RTSP 交互过程
- 自刷新模式与断电模式之间的区别
- Redis中的压缩列表
- Wordpress 外网访问时不显示图片解决办法
- 事件处理程序(HTML,DOM0,DOM2,IE)
- case when then 的两种写法
- ASCII Art之tone-based生成方法实现
- Ionic2使用百度地图和html5 geolocation的一些注意事项
- FL Studio混合器之效果器插槽部分讲解