一緒に書く習慣をつけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して2日目です。クリックしてイベントの詳細をご覧ください。
序文
簡単な使い方を実装した後もMediaPlayer
、実際の開発にはまだまだ多くの問題がありますが、ここでは問題をまとめて理由と解決策を記録し、開発概要です。
問題の要約
TrackInfoリソース情報クエリ
リソースをロードし、開発中にメソッドを実行したprepareAsync
後、コールバックメソッドでリソースTrackInfoを取得します。当初は、この方法でビデオサイズ情報を取得することが期待されていました。たとえば、メソッドMediaExtractor
を介してgetTrackFormat
リソース情報を取得する場合などです。 TrackInfo
オブジェクトは内部で取得できますが、実際のソースコードでは、戻り値が空MediaFormat
であることがわかります。MediaFormat
public MediaFormat getFormat() {
if (mTrackType == MEDIA_TRACK_TYPE_TIMEDTEXT
|| mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
return mFormat;
}
return null;
}
复制代码
したがって、MediaPlayer
内部推定を使用してリソースファイルを直接取得できない場合は、MediaExtractor
外部でのみ取得できます。
一時停止後に開始が失敗する
MediaPlayer
シーケンス図からメソッドが呼び出されていることがわかります。呼び出された場合は、pause
再度呼び出してstart
も問題ありません。タイミングが合っている場合はstop
、メソッドを再実行prepare
して、リソースが再準備されるのを待ってから再生する必要があります。
- 質問1
実際の開発で遭遇する問題は、プレイヤーがActivity
バックグラウンドにいるときに、ライフサイクルとページがバインドされ、また呼び出されるため、ライフサイクルActivity
のメソッドが呼び出されることです。最後に、理由がわかりました。現在は状態なので、実行メソッドのために再生する必要があります。onStop
MediaPlayer
stop
MediaPlayer
stop
MediaPlayer
prepare
問題1は、プレーヤーがバックグラウンドに戻った後にリソースを再生できるが、バインディングSurfaceView
が黒い画面であるという問題を解決することです。
- 質問2
拘束力のあるSurfaceView
黒い画面の状況は、基本的に質問1と同様です。SurfaceView
ライフサイクルもあるためActivity
、バックグラウンドで呼び出されると、プレーヤーへsurfaceDestroyed
の元のバインドが期限切れになり、再バインドする必要があります。SurfaceView
Surface
元のロジックは、メソッドで1回だけ初期化してバインドすることであるため、メソッドでのみバインドすることは不適切post
と思われます。post
surfaceView.post(new Runnable() {
@Override
public void run() {
AndroidMediaPlayer.Builder builder = new AndroidMediaPlayer.Builder(TestSimpleMediaPlayerActivity.this,uri,listener);
builder.withSurface(surfaceView.getHolder().getSurface());
androidMediaPlayer = builder.createPlayer();
androidMediaPlayer.prepareAsync();
}
});
复制代码
surfaceView
バインディング作業は、のコールバックメソッドからsurfaceCreated
実行されSurface
、ページがバックグラウンドから入力されるたびにバインディングを更新できるようにします。
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
if(androidMediaPlayer != null)
androidMediaPlayer.setSurface(surfaceView.getHolder().getSurface());
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
Log.d("<> surfaceView","surfaceChanged");
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
Log.d("<> surfaceView","surfaceDestroyed");
}
});
复制代码
- 質問3
MediaPlayer
もう1つの問題は、再生進行状況のコールバックインターフェイスが提供されていないことです。MediaPlayer
現在の再生の進行状況を取得する方法はありますgetCurrentPosition
が、リアルタイムアクセスを取得する機能を提供するためにカプセル化することはできないため、開発者は自分でリアルタイムアクセスの方法を実装する必要があります。
Thread
現在の再生ミリ秒値は、プレーヤーメソッドをループで継続的に呼び出すことで取得できgetCurrentPosition
ます。また、実際のビジネスニーズに応じて遅延処理を追加することもできます。
private class PlayerThread extends Thread{
private boolean toGet = false;
public void startGet(){
toGet = true;
}
public void stopGet(){
toGet = true;
}
@Override
public void run() {
super.run();
while (toGet){
if(mMediaPlayer != null){
int position = mMediaPlayer.getCurrentPosition();
if(mListener != null){
playerInfo.playerProgress = position;
mListener.onPlayerInfoCallBack(playerInfo);
}
}
}
}
}
复制代码
要約する
MediaPlayer
使い方は簡単ですが、実装開発ではまだいくつかの詳細が公開されます。完全なプレーヤー機能を本当に開発して実装したい場合でも、多くの機能シナリオを改善して検討する必要がありMediaPlayer
ます。さらに深く掘り下げることができるいくつかの基本的な機能があります。