Android プラットフォームおよびイントラネット RTSP ゲートウェイ用の軽量 RTSP サービスを構築していたときに、複数の RTSP ストリームを同時にリリースするにはどうすればよいか?という問題が発生しました。
この質問に答えることは実際には難しくありません。Daniu Live SDK がこのモジュールを設計したとき、複数のストリームを持つサービスの状況を考慮しました。おおよその技術的な実装は次のとおりです。
RTSP サービスを開始します。
RTSP サービスを開始すると、OpenRtspServer() が rtsp_handle_ を返します。これは RTSP サービスに対応します。
class ButtonRtspServiceListener implements OnClickListener {
public void onClick(View v) {
if (isRTSPServiceRunning) {
stopRtspService();
btnRtspService.setText("启动RTSP服务");
btnRtspPublisher.setEnabled(false);
isRTSPServiceRunning = false;
return;
}
if(!OpenPushHandle())
{
return;
}
Log.i(TAG, "onClick start rtsp service..");
rtsp_handle_ = libPublisher.OpenRtspServer(0);
if (rtsp_handle_ == 0) {
Log.e(TAG, "创建rtsp server实例失败! 请检查SDK有效性");
} else {
int port = 8554;
if (libPublisher.SetRtspServerPort(rtsp_handle_, port) != 0) {
libPublisher.CloseRtspServer(rtsp_handle_);
rtsp_handle_ = 0;
Log.e(TAG, "创建rtsp server端口失败! 请检查端口是否重复或者端口不在范围内!");
}
//String user_name = "admin";
//String password = "12345";
//libPublisher.SetRtspServerUserNamePassword(rtsp_handle_, user_name, password);
if (libPublisher.StartRtspServer(rtsp_handle_, 0) == 0) {
Log.i(TAG, "启动rtsp server 成功!");
} else {
libPublisher.CloseRtspServer(rtsp_handle_);
rtsp_handle_ = 0;
Log.e(TAG, "启动rtsp server失败! 请检查设置的端口是否被占用!");
}
btnRtspService.setText("停止RTSP服务");
btnRtspPublisher.setEnabled(true);
isRTSPServiceRunning = true;
}
}
}
このRTSPサービスを停止するにはどうすればよいですか?
//发布/停止RTSP流
class ButtonRtspPublisherListener implements OnClickListener {
public void onClick(View v) {
if (isRTSPPublisherRunning) {
stopRtspPublisher();
btnRtspPublisher.setText("发布RTSP流");
btnGetRtspSessionNumbers.setEnabled(false);
btnRtspService.setEnabled(true);
}
else
{
Log.i(TAG, "onClick start rtsp publisher..");
boolean startRet = StartRtspStream();
if (!startRet) {
Log.e(TAG, "Failed to call StartRtspStream().");
return;
}
btnRtspPublisher.setText("停止RTSP流");
btnGetRtspSessionNumbers.setEnabled(true);
btnRtspService.setEnabled(false);
}
}
};
サービスを開始して複数の RTSP ストリーム (さまざまなデータ ソースと RTSP ストリーミング URL に対応) を公開するにはどうすればよいですか?
実際には、パブリッシュされた各 RTSP ストリームが PublisherHandle に対応し、オーディオおよびビデオ データ配信もこの PublisherHandle を渡すことを確認してください。
private boolean StartRtspStream(long publisherHandle, String rtsp_stream_name)
{
if (isRTSPPublisherRunning)
return false;
libPublisher.SetRtspStreamName(publisherHandle, rtsp_stream_name);
libPublisher.AddRtspStreamServer(publisherHandle, rtsp_handle_, 0);
if (libPublisher.StartRtspStream(publisherHandle, 0) != 0)
{
Log.e(TAG, "调用发布rtsp流接口失败!");
if (!isPushing)
{
libPublisher.SmartPublisherClose(publisherHandle);
publisherHandle = 0;
}
return false;
}
isRTSPPublisherRunning = true;
return true;
}
RTSP ストリームの公開を停止します。
//停止发布RTSP流
private void stopRtspPublisher(long publisherHandle)
{
if(!isRTSPPublisherRunning)
return;
isRTSPPublisherRunning = false;
if (null == libPublisher || 0 == publisherHandle)
return;
libPublisher.StopRtspStream(publisherHandle);
if (!isPushing && !isRTSPServiceRunning)
{
releasePublisherHandle();
}
}
公開された各 RTSP ストリームはイベント コールバックに対応し、外部にストリーミングできる RTSP URL を返します。
class EventHandlePublisherV2 implements NTSmartEventCallbackV2 {
@Override
public void onNTSmartEventCallbackV2(long handle, int id, long param1, long param2, String param3, String param4, Object param5) {
Log.i(TAG, "EventHandlePublisherV2: handle=" + handle + " id:" + id);
String publisher_event = "";
switch (id) {
...
case NTSmartEventID.EVENT_DANIULIVE_ERC_PUBLISHER_RTSP_URL:
publisher_event = "RTSP服务URL: " + param3;
break;
...
}
}
}
単一サービスのセッション リンクの数を取得する必要がある場合:
//获取RTSP会话数
class ButtonGetRtspSessionNumbersListener implements OnClickListener {
public void onClick(View v) {
if (libPublisher != null && rtsp_handle_ != 0) {
int session_numbers = libPublisher.GetRtspServerClientSessionNumbers(rtsp_handle_);
Log.i(TAG, "GetRtspSessionNumbers: " + session_numbers);
PopRtspSessionNumberDialog(session_numbers);
}
}
};
上記は一般的な設計アイデアであり、興味のある開発者はそれを参照できます。