このトピックでは、Android プレーヤーソフトウェア開発キット (SDK) を使用する際の一般的な問題とソリューションについて説明します。
開発に関する問題
現在の再生進捗の取得方法
デフォルトでは、プレーヤー SDK は 500 ms ごとに再生進捗のコールバックを提供します。このコールバック間隔は変更できます。現在の再生進捗をより頻繁に取得するには、間隔を短くします。次のコードに例を示します。
// コールバック間隔を変更します。
PlayerConfig config = mAliyunLivePlayer.getConfig();
config.mPositionTimerIntervalMs = 100;// コールバック間隔 (ms)。
mAliyunLivePlayer.setConfig(config);
mAliPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
@Override
public void onInfo(InfoBean infoBean) {
if(infoBean.getCode() == InfoCode.CurrentPosition){
// 現在の再生進捗。
long currentPosition = infoBean.getExtraValue();
}
}
});ソースのオーディオデータとビデオデータの取得
RAW オーディオデータとビデオデータを取得するには、ソフトウェアデコードに切り替えて、暗号化されていないビデオを再生します。次のコードに例を示します。
// ソフトウェアデコードに切り替えます。
mAliPlayer.enableHardwareDecoder(false);
IPlayer.RenderFrameCallbackConfig renderFrameCallbackConfig = new IPlayer.RenderFrameCallbackConfig();
// 基になるビデオデータアドレスのみを返すかどうかを指定します。デフォルト値: true。
renderFrameCallbackConfig.mVideoDataAddr = false;
// 基になるオーディオデータアドレスのみを返すかどうかを指定します。デフォルト値: false。
renderFrameCallbackConfig.mAudioDataAddr = false;
mAliPlayer.setRenderFrameCallbackConfig(renderFrameCallbackConfig);
mAliPlayer.setOnRenderFrameCallback(new IPlayer.OnRenderFrameCallback() {
@Override
public boolean onRenderFrame(FrameInfo frameInfo) {
return false;
}
});ビデオの幅と高さの取得
ビデオの幅と高さは、次の 3 つの方法のいずれかで取得できます。
AliPlayer インスタンスが `prepare` メソッドを完了し、`prepared` 状態になった後、次のメソッドを使用して幅と高さを取得できます。
mAliyunPlayer.setOnPreparedListener(new IPlayer.OnPreparedListener() { @Override public void onPrepared() { mAliyunPlayer.getVideoWidth(); mAliyunPlayer.getVideoHeight(); } });ビデオサイズの変更コールバックをリッスンします。
mAliyunPlayer.setOnVideoSizeChangedListener(new IPlayer.OnVideoSizeChangedListener() { @Override public void onVideoSizeChanged(int width, int height) { } });`track` メソッドを使用して幅と高さを取得します。
mAliyunPlayer.setOnTrackReadyListener(new IPlayer.OnTrackReadyListener() { @Override public void onTrackReady(MediaInfo mediaInfo) { List<TrackInfo> trackInfos = mediaInfo.getTrackInfos(); for (TrackInfo trackInfo : trackInfos) { if(trackInfo.getType() == TrackInfo.Type.TYPE_VIDEO){ trackInfo.getVideoWidth(); trackInfo.getVideoHeight(); } } } });
プレーヤー内の各ビデオフレームのピクセルを取得する方法
Android プレーヤーの場合、OnRenderFrameCallback コールバックをリッスンすることでピクセルを取得できます。
player.setOnRenderFrameCallback(frameInfo -> {
if (frameInfo.frameType == FrameInfo.FrameType_video) {
// ビデオデータ
} else {
// オーディオデータ
}
return false;
});自動ビットレート切り替えロジック
mAliPlayer.selectTrack(TrackInfo.AUTO_SELECT_INDEX) インターフェイスを呼び出して自動ビットレート切り替えを有効にすると、プレーヤー SDK は現在のネットワーク速度を計算します。ネットワーク速度が次のビットレートレベルを 10 秒間サポートできる場合、プレーヤーはそのビットレートに切り替えます。それ以外の場合、プレーヤーは切り替えません。
高ビットレートから低ビットレートに切り替える場合、プレーヤーはキャッシュされた高ビットレートのコンテンツが再生された後に切り替えを行います。この切り替えは、ネットワーク速度が 10 秒間、より低いビットレートのレベルまで低下した場合に発生します。
低ビットレートから高ビットレートに切り替える場合、プレーヤーはすぐに切り替えます。この切り替えは、ネットワーク速度が 10 秒間、次のビットレートレベルまで増加した場合に発生します。
自動ビットレート切り替えを有効にするには、まずコンソールでビデオをアダプティブビットレートストリームにトランスコードする必要があります。次に、プレーヤーがアダプティブビットレートストリームを取得するように指定します。次のコードは、VidAuth 再生メソッドを使用する例を示しています。
VidAuth vidAuth = new VidAuth();
List<Definition> list = new ArrayList<>();
list.add(Definition.DEFINITION_AUTO);
vidAuth.setDefinition(list);カスタムリトライロジック
ネットワークリトライのシナリオでは、プレーヤー SDK はデフォルトで 2 回リトライし、各試行のネットワークタイムアウトは 15 秒です。両方のリトライが失敗した場合、`Error` コールバックがトリガーされます。
リトライロジックはカスタマイズできます。リトライがトリガーされると、リトライイベントが外部サービスに送信され、そこで特定のリトライロジックが決定されます。次のコードに例を示します。
PlayerConfig config = mAliPlayer.getConfig();
// 1. リトライ回数を設定します。この例では、0 に設定されています。
config.mNetworkRetryCount = 0;
mAliPlayer.setConfig(config);
mAliPlayer.setOnInfoListener(new IPlayer.OnInfoListener() {
@Override
public void onInfo(InfoBean infoBean) {
// 2. リトライイベントをリッスンします。
if(infoBean.getCode() == InfoCode.NetworkRetry){
// TODO: 必要に応じてロジックを処理します。
}
}
});ARTC ストリーム再生中に unsupported protocol エラーが発生する
原因 1: プレーヤー SDK は統合されていますが、ブリッジレイヤー (AlivcArtc) とリアルタイムストリーミング (RTS) コンポーネント (RtsSDK) が統合されていません。
ソリューション: コンポーネントを統合します。詳細については、「Android での RTS ストリームフェッチングの実装」をご参照ください。
原因 2: ブリッジレイヤー (AlivcArtc) のバージョンがプレーヤーのバージョンと一致しません。
ソリューション: ブリッジレイヤー (AlivcArtc) とプレーヤーは同じバージョン番号である必要があります。詳細については、「Android での RTS ストリームフェッチングの実装」をご参照ください。
原因 3: RTS コンポーネント (RtsSDK) がロードされていません。
ソリューション: 必要に応じて、Application ファイルまたはターゲットの Activity で RTS コンポーネント (RtsSDK) をロードします。
static {
System.loadLibrary("RtsSDK");
}原因 4: minSDK のバージョンが高すぎて、ブリッジレイヤー (AlivcArtc) が正しくロードされていません。
// 1. minSdk を変更
minSdk を 21 にダウングレード
// 2. ARTC ライブラリを手動でロード
static {
System.loadLibrary("RtsSDK");
System.loadLibrary("cicada_plugin_artcSource");
}シーク操作後にプログレスバーが逆戻りする
原因: デフォルトでは、プレーヤーは不正確なシークを使用します。シーク操作後、プレーヤーはシークポイントに近いキーフレームから再生を開始します。
ソリューション: 正確なシークモードに切り替えます。
正確なシークモードと不正確なシークモードの切り替え方法
次のコードは、シークモードを切り替える方法を示しています。
// 不正確なシーク。
mAliPlayer.seekTo(1000);
mAliPlayer.seekTo(1000, IPlayer.SeekMode.Inaccurate);
// 正確なシーク。
mAliPlayer.seekTo(1000,IPlayer.SeekMode.Accurate);正確なシークモードに切り替えてもプログレスバーが逆戻りする
原因: 正確なシークは不正確なシークよりも時間がかかります。シークポイントから最も近いキーフレームまでの距離が長く、正確なシークの最大間隔を超えると、プレーヤー SDK は自動的に不正確なシークに切り替わります。これにより、プログレスバーが逆戻りします。
ソリューション: インターフェイスを使用して、正確なシークの最大間隔を設定できます。最大間隔を長くすると、正確なシークが不正確なシークに切り替わる頻度が減り、シークの精度が向上します。ただし、間隔が長いと、シークポイントがキーフレームから遠い場合にシーク操作に時間がかかります。ビジネスニーズに基づいて、正確なシークの最大間隔を合理的に設定する必要があります。次のコードに例を示します。
// 単位: ms。
mAliPlayer.setMaxAccurateSeekDelta(10000);ローカルキャッシュ: キャッシュディレクトリを内部ストレージディレクトリに設定できますか?
はい、できます。Android デバイスの外部ストレージディレクトリを内部ストレージディレクトリに変更できます。ただし、キャッシュが正しく機能するためには、内部ストレージディレクトリへのアクセス権限があることを確認する必要があります。
ビデオのキャッシュ中に `encrypt check fail` エラーが発生する
キャッシュはダウンロードに似ています。セキュアダウンロードが有効になっている場合、暗号化検証ファイルがアプリ情報と一致することを確認する必要があります。オフラインダウンロードで生成された暗号化検証ファイルをダウンロードし、プレーヤー SDK に保存する必要があります。詳細については、「ビデオのダウンロード」をご参照ください。そうしないと、キャッシュまたはダウンロードが失敗します。
再生に関する問題
プレーヤー作成時にクラッシュが発生する
次のように問題をトラブルシューティングします。
CPU アーキテクチャが x86 かどうかを確認します。
プレーヤー SDK は arm64-v8a と armeabi-v7a アーキテクチャのみをサポートしています。x86 アーキテクチャはサポートしていません。
プロジェクトにプレーヤー SDK の .so ファイルと Maven 依存関係の両方が統合されているかどうかを確認します。
たとえば、`build.gradle` で Maven 依存関係を使用してプレーヤー SDK を統合し、さらにプロジェクトのモジュールの `libs` ディレクトリにプレーヤー関連の動的ライブラリを統合している場合があります。
推奨されるソリューション: 両方の方法を使用している場合は、動的ライブラリを削除し、Maven 依存関係のみを使用してください。動的ライブラリを統合する必要がある場合は、すべてのプレーヤー SDK 関連の .so ファイルが同じバージョンであることを確認してください。プレーヤー SDK の統合方法と動的ライブラリの取得方法については、「SDK の統合」をご参照ください。次の図は、プレーヤー関連の動的ライブラリを示しています。

部分的なパッケージを統合した場合、AlivcFFmpeg のバージョン依存関係が正しいことを確認します。
AlivcFFmpeg のバージョン依存関係については、「AlivcFFmpeg のバージョン依存関係」をご参照ください。
プレーヤーの実行中にクラッシュが発生する
次のように問題をトラブルシューティングします。
クラッシュがプレーヤー SDK 内で発生したかどうかを確認します。
AliyunPlayerプレフィックスを持つクラッシュスタックを確認します。このプレフィックスを持つスタックが存在する場合、問題はプレーヤー SDK にあります。プレーヤー SDK の最新バージョンにアップグレードし、問題が修正されているか確認します。
問題が解決しない場合は、関連するクラッシュファイル (すべてのスレッドを含む)、クラッシュログ、およびクラッシュシナリオの情報を準備します。詳細については、「問題ログの取得方法」をご参照ください。
ビデオ再生中に黒枠が表示される
次のように問題をトラブルシューティングします。
ソースビデオ自体に黒枠があるかどうかを確認します。
次のインターフェイスを使用して、プレーヤーのスケーリングモードを調整できます。
/* SCALE_ASPECT_FILL: 画面に比例して塗りつぶします。ビデオはトリミングされます。 SCALE_ASPECT_FIT: ビデオを比例してスケーリングします。黒枠が表示されることがあります。 SCALE_TO_FILL: 比率を維持せずに画面を塗りつぶします。ビデオは歪みます。 */ mAliPlayer.setScaleMode();スケーリングモードがニーズに合わない場合は、アプリケーション層で SurfaceView または TextureView のサイズを調整できます。
音声は再生されるがビデオが表示されない
次のように問題をトラブルシューティングします。
別のプレーヤーでビデオを再生し、オーディオのみのファイルかどうかを確認します。
ビデオをレンダリングするビューが正しく設定されていることを確認します。たとえば、プレーヤーに表示ビューが設定されているか、再生インターフェイスから削除されているかを確認します。表示ビューの設定手順については、「基本機能」の [ステップ 4] をご参照ください。
読み取り権限のあるローカルビデオの再生時に `Invalid argument` エラーが発生する
読み取り権限のあるローカルビデオを再生する際に `Invalid argument` エラーが発生した場合は、ファイル名と絶対パスを確認してください。パスに漢字とスペースの組み合わせを使用しないでください。
読み取り権限のあるローカルビデオの再生時に `Permission denied` エラーが発生する
Android 10 (Android Q) 以降を実行しているデバイスでストレージ権限を正しく使用するには、AndroidManifest.xml の application タグに android:requestLegacyExternalStorage="true" を追加する必要があります。これは、これらの Android バージョンでスコープ付きストレージ機能が導入されたためです。
ビデオ再生中に `Redirect to a url` エラーが時々発生する
このエラーは、再生中のビデオのソースがハイジャックされているために発生する可能性があります。この問題を解決するには、プレーヤーの HTTPDNS 機能を有効にすることをお勧めします。詳細については、「Android 用の HTTPDNS の設定」をご参照ください。
フルスクリーン再生中にノッチ付き画面で黒い通知バーが点滅する
これは、没入型ステータスバーを設定することで解決できます。
MOV ビデオの再生に失敗した
Android プレーヤー SDK は MOV フォーマットのビデオをサポートしています。MOV ビデオの再生に失敗する場合、ソースビデオ内で moov アトム (オーディオおよびビデオデータのインデックス) が mdat アトム (オーディオおよびビデオデータ) の後にあることが原因である可能性があります。この問題は、ソースビデオをトランスコードして moov アトムを mdat アトムの前に移動することで解決できます。詳細については、「ステップ 2: ストリームのトラブルシューティング」をご参照ください。
初期化または再生中にエラーが発生し、プレーヤー SDK の .so 動的ライブラリが見つからないことを示す
次のように問題をトラブルシューティングします。
CPU アーキテクチャが要件を満たしているか確認します。
プレーヤー SDK は、arm64-v8a および armeabi-v7a アーキテクチャの動的ライブラリのみをサポートしています。
プレーヤー SDK のバージョンが古すぎないか確認します。
プレーヤー SDK V5.4.6.0-full 以前を使用している場合は、V5.4.6.0-full-15467853 以降のバージョンにアップグレードすることをお勧めします。プレーヤー SDK の最新および過去のバージョンについては、「Android SDK リリースノート」をご参照ください。
AliListPlayer を使用して HLS (m3u8) ビデオを再生する際にエラーが発生する
V5.4.5.0 より前のバージョンのプレーヤー SDK は、リストプレーヤー AliListPlayer を使用した HLS (m3u8) ビデオの再生をサポートしていません。V5.4.5.0 以降、HLS (m3u8) ビデオがサポートされています。ただし、ローカルキャッシュを有効にする必要があります。ローカルキャッシュを有効にする方法については、「ローカルキャッシュ」をご参照ください。
Android プレーヤー SDK は、Android プロジェクトの assets および raw フォルダからのビデオ再生をサポートしていますか?
いいえ、サポートしていません。ビデオを携帯電話のストレージにコピーし、絶対パスを使用してビデオを再生する必要があります。
HLS ビデオストリームにローカルキャッシュを設定した後、403 エラーが発生して再生に失敗する
症状: ローカルキャッシュを有効にして VidAuth 再生メソッドを使用して HLS (M3U8) ビデオストリームを再生すると、再生に失敗し、403 エラーが報告されます。
原因: ローカルキャッシュを有効にした後、ビデオが完全にキャッシュされる前に再生を終了すると、次に再生を開始するときに、キャッシュされていない部分が前回のセッションの期限切れの VidAuth 情報を使用してリクエストされます。これにより、認証に失敗し、403 エラーが発生します。
ソリューション: プレーヤー SDK V5.5.4.0 以降では、ビデオ再生 URL に認証パラメーターが含まれ、再生プロトコルが HLS の場合、PlayerConfig.mEnableStrictAuthMode フィールドを設定して、異なる認証モードを選択できます。デフォルト値は `false` です。
非厳密認証 (`false`): 認証トークンもキャッシュされます。以前にメディアの一部のみがキャッシュされていた場合、プレーヤーはキャッシュされたトークンを使用して残りの部分をリクエストします。トークンの有効期間が短い場合、これにより再生が失敗する可能性があります。
厳密認証 (`true`): 認証トークンはキャッシュされません。再生を開始するたびに新しいトークンが必要です。これにより、ネットワーク接続が利用できない場合に再生が失敗します。
Android プレーヤー SDK はダウンロード中の再生をサポートしていますか?
いいえ、サポートしていません。Android プレーヤー SDK は、ローカルキャッシュ機能を有効にすると、再生中にビデオファイルをキャッシュおよびダウンロードすることをサポートします。次回ビデオを再生するときは、キャッシュされたファイルが直接再生されます。SDK は現在、元のファイルディレクトリから移動されたローカルにキャッシュされたビデオファイルの再生をサポートしていません。
Android プレーヤー SDK はビデオのバッファリング速度の取得をサポートしていますか?
はい、サポートしています。Android プレーヤー SDK は、バッファリング速度、リアルタイムレンダリングフレームレート、オーディオおよびビデオビットレート、ネットワークダウンロードビットレートの取得をサポートしています。詳細については、「再生情報の取得」をご参照ください。
HDR ビデオの異常な再生
Android プレーヤー SDK は現在、回転角度を持つ HDR ビデオをサポートしていません。これらのタイプのビデオでは再生エラーが発生する可能性があります。
ビデオが複数の解像度にトランスコードされた場合、プレーヤー SDK はデフォルトでどの解像度を再生しますか?
解像度のデフォルトの再生順序は、FD、LD、SD、HD、2K、4K、OD です。解像度については、「解像度」をご参照ください。プレーヤー SDK はこの順序で左から右に解像度を検索し、最初に見つかったものを再生します。
デフォルトの再生解像度を指定する方法
次のコードに例を示します。
// VidSts 再生メソッドを例として使用します。
VidSts vidSts = new VidSts();
// vid、AccessKeyId、AccessKeySecret、token などのパラメーターを設定するコードは省略されています。詳細については、「基本機能」トピックのプレーヤー作成設定をご参照ください。
/*
パラメーター 1: 希望する再生解像度。有効な値: FD、LD、SD、HD、2K、4K、OD。
パラメーター 2: 希望する解像度の再生を強制するかどうかを指定します。false: 希望する解像度の再生を強制しません。プレーヤー SDK はデフォルトの順序に基づいて再生する解像度を検索します。true: 希望する解像度の再生を強制します。希望する解像度が見つからない場合、ビデオは再生されません。
*/
vidSts.setQuality("",false);解像度に複数のストリームがある場合、プレーヤー SDK はどのストリームを再生しますか?
解像度に複数のストリームがある場合、プレーヤー SDK は最新のストリームを再生します。
その他の問題
ウォーターマークなしでビデオを再生し、ウォーターマーク付きでダウンロードする方法
ビデオを複数の解像度にトランスコードします。ウォーターマークなしの解像度を再生し、ウォーターマーク付きの解像度をダウンロードします。
問題ログの取得方法
Alibaba Cloud に技術サポートをリクエストする際、問題ログを提出することで、より効率的に問題を解決できます。問題ログは次のように取得できます。
問題ログを取得します。
問題ログを取得する前に、ログレベルを
AF_LOG_LEVEL_TRACEに設定することをお勧めします。詳細については、「SDK ログの取得」をご参照ください。生成されたログを Alibaba Cloud の技術サポートに提供します。