ストリームメディアプロトコルが日々多様化している中、TMIO SDK (Tencent Media IO SDK)は主流のプロトコルを統合、最適化、拡張していることで、複数のプロトコルを開発、デバッグする煩雑な作業からユーザを解放し、安定して動作できるメディアアプリケーションを開発することに協力します。
TMIO SDKは現在、SRTやQUICなどの主流のメディアプロトコルを最適化、拡張し、同時に自社開発の伝送制御プロトコルETC(正式名称:Elastic Transmission Control)を追加し、今後も他の主流のプロトコルの最適化および拡張機能を追加し続けます。
TMIOはSRTプロトコルをサポートし、弱いネットワークや長距離伝送のシナリオで使用して、アップリンクの安定性とダウンリンクのスムーズさを向上させることができます。
次のテストシナリオでは、パケットロス率が10%の場合にRTMPプッシュにラグが発生し、パケットロス率が10%または30%の場合でも、SRTプッシュは安定性と低遅延を維持できます。
SRTベースのストリームメディア転送機能。
ランダムなパケットロスに対する強い耐性。
ARQとタイムアウトポリシーをベースにした再転送メカニズム。
UDTベースの低遅延、安全安心な転送設計。
マルチリンク転送機能。既存機能をリンク集約機能まで拡張:
マルチリンク転送機能を使用し、複数のリンクを設定してデータ転送を実装できます。特に4G/5Gネットワークが普及している今、モバイル端末デバイスはデータ転送にWi-Fiとモバイルデータネットワークのどちらかに使用することもできます。そのうちの一方が切断されても、1つのリンクさえ使用できれば、通信の安定性を確保できます。
機能モード | の説明 |
---|---|
ブロードキャストモード | 複数の接続を設定することで冗長送信を実装し、データの完全性と接続の信頼性を確保できます。 |
マスター/スレーブ | リンクの安定性と信頼性を参考にして、同一時間に1つのリンクだけがアクティブになっており、リアルタイムで質の良いリンクを選択してデータを転送します。リンクの安定性と信頼性を確保した上で、冗長なデータによって無駄な帯域幅の消費を減らすことができます。 |
集約モード | 高いビットレートと帯域幅を要求するシーンでは、単一リンクの帯域幅がニーズを満たせない場合、集約モードを使用すれば、データを複数のリンクに分割して転送すると同時に、受信側で受信したデータを組み立てます。これにより、帯域幅が増えます。 |
QUICによるストリーミングメディア伝送機能
自社開発の伝送制御プロトコルETC
以下ではRTMP over SRTプロトコルを例として説明します。
Tmio Proxyの作成:
std::unique_ptr<tmio::TmioProxy> proxy_ = tmio::TmioProxy::createUnique();
リスナーの設定:
void setListener(TmioProxyListener *listener);
TmioProxyListener リスナーインターフェースは以下のとおりです:
ユーザはこのコールバックの中でTmioのパラメータを設定できます。**tmio-preset.h
を使用して提供できる補助メソッドを簡単に設定できます**。
/*
void onTmioConfig(Tmio *tmio);
*/
void onTmioConfig(tmio::Tmio *tmio) override {
auto protocol = tmio->getProtocol();
if (protocol == tmio::Protocol::SRT) {
tmio::SrtPreset::rtmp(tmio);
} else if (protocol == tmio::Protocol::RIST) {
tmio->setIntOption(tmio::base_options::RECV_SEND_FLAGS,
tmio::base_options::FLAG_SEND);
}
}
std::error_code start(const std::string &local_url, const std::string &remote_url, void * config=nullptr)
パラメータ | 説明 |
---|---|
local_url | TCP Schemeのみをサポートします。フォーマットはtcp://${ip}:${port} です。portは0で構いません。0の場合、ランダムにポートに関連付け、onStart()コールバックで正常に関連付けたポート番号をアプリケーションに返します。0ポートを使用すれば、ポート占有や権限なしによる関連付け失敗を回避できます |
remote_url | リモートサーバーURL |
config | 設定パラメータ。このパラメータは、SRT bonding機能およびQUIC H3プロトコルが有効になっている場合に使用され、具体的にはtmio.h 配下のTmioFeatureConfig構造体に基づいて定義してください |
proxy_->start(local_url, remote_url, NULL);
bonding マルチリンク(ソースコード例)
tmio::TmioFeatureConfig option;
option_.protocol = tmio::Protocol::SRT;
option_.trans_mode = static_cast<int>(tmio::SrtTransMode::SRT_TRANS_BACKUP);
/*-----------------------------------------------------------*/
{
//作成するリンク数に応じて複数のリンクを追加できます
option_.addAvailableNet(net_name, local_addr, remote_url, 0, weight, -1);
}
/*-----------------------------------------------------------*/
proxy_->start(local_url, remote_url, &option_);
/*
void stop();
*/
proxy_.stop();
tmio_ = tmio::TmioFactory::createUnique(tmio::Protocol::SRT);
tmio::SrtPreset::mpegTsLossless(tmio_.get());
tmio_->setIntOption(tmio::srt_options::CONNECT_TIMEOUT, 4000);
tmio_->setBoolOption(tmio::base_options::THREAD_SAFE_CHECK, true);
TmioFactory
で作成します。tmio-option.h
をご参照ください。tmio-preset.h
をご参照ください。
//パラメータのプロパティによって適切な設定を選択します
bool setBoolOption(const std::string &optname, bool value);
bool setIntOption(const std::string &optname, int64_t value);
bool setDoubleOption(const std::string &optname, double value);
bool setStrOption(const std::string &optname, const std::string &value);
...
/**
<span class="hljs-keyword">void</span> *config = <span class="hljs-literal">nullptr</span>)</span> </span>= <span class="hljs-number">0</span>;
//デフォルトではシングルリンクとします
auto err = tmio->open(TMIO_SRT_URL);
if (err) {
LOGE("open failed, %d, %s", err.value(), err.message().c_str());
}
tmio.h
ファイル構造のTmioFeatureConfigを参考にして定義します。tmio::TmioFeatureConfig option_;
option_.protocol = tmio::Protocol::SRT;
option_.trans_mode = static_cast<int>(tmio::SrtTransMode::SRT_TRANS_BACKUP);
option_.addAvailableNet(net_name, local_addr, remote_url, 0, weight, -1);
//bonding マルチリンク
auto err = tmio_->open(TMIO_SRT_URL, &option_);
if (err) {
LOGE("open failed, %d, %s", err.value(), err.message().c_str());
}
int ret = tmio_->send(buf.data(), datalen, err);
if (ret < 0) {
LOGE("send failed, %d, %s", err.value(), err.message().c_str());
break;
}
/**
using RecvCallback = std::function<bool(const uint8_t *buf, int len, const std::error_code &err)>;
/**
receive data in event loop
recvLoop() block current thread, receive data in a loop and pass the data to recvCallback
@param recvCallback return true to continue the receive loop, false for break
/
virtual void recvLoop(const RecvCallback &recvCallback) = 0;
上位のアプリケーションを繰り返して読み取ります
while (true) {
ret = tmio_->recv(buf.data(), buf.size(), err);
if (ret < 0) {
LOGE("recv error: %d, %s", err.value(), err.message().c_str());
break;
}
...
}
コールバックを読み取ります
FILE *file = fopen(output_path, "w");
tmio_->recvLoop([file](const uint8_t *buf, int len,
const std::error_code &err) {
if (len < 0) {
fwrite(buf, 1, len, file);
} else if (len < 0) {
LOGE("recv error: %d, %s", err.value(), err.message().c_str());
}
return true;
});
tmio_->close();
tmio::PerfStats stats_;
tmio_->control(tmio::ControlCmd::GET_STATS, &stats_);
TMIO SDKへのアクセスは、最新のAPIインターフェースおよびDemoの説明を参照することができます。詳細については、TMIOアクセスの詳細をご参照ください。
マルチリンク機能を使用する前提は、デバイスに複数の使用可能なネットワークインターフェースがあることです。なお、OSがAndroidのデバイスの場合、6.0(api level >=23)以降のバージョンも要求しています。
Android系の携帯電話がWi-Fiに接続していれば、4G/5Gモバイルネットワークをそのまま使用できます。4G/5Gモバイルネットワークを使用するには、4G/5Gモバイルネットワークを使用する権限を申請する必要があります。ソースコードは以下のとおりです:
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest request = new NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build();
ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback(){
@Override
public void onAvailable(@NonNull Network network) {
Log.d(TAG, 「モバイルデータインターネットチャネルはオンです.");
super.onAvailable(network);
}
}
この記事はお役に立ちましたか?