我目前正在开发具有视频和音频功能的应用程序的一部分,并且最近开始重构代码库。目标是集成MediaSession/ MediaController
和MediaBrowserService/ MediaBrowser
框架。
我们更具体地使用ExoPlayer
和PlayerControlView
,将PlayerView用于视频和音频组件,并且需要PlayerControlView
引用播放器实例:
/**
* Sets the {@link Player} to control.
*
* @param player The {@link Player} to control, or {@code null} to detach the current player. Only
* players which are accessed on the main thread are supported ({@code
* player.getApplicationLooper() == Looper.getMainLooper()}).
*/
public void setPlayer(@Nullable Player player) {...
但是,在
MediaBrowserService
的android developers post和documentation下,播放器实例应包含在该服务下。此外,客户端站点(MediaBrowser和MediaController)通过connect()
方法和MediaBrowserConnectionCallback进行对话以为其提供服务的唯一方法是,无法将播放器的实例传递给PlayerControlView(或相反)。我尝试使用各种回调(例如MediaSessionCompat.Callback),但SimpleExoPlayer或PlayerControlView都不是可打包的。
在传统服务中,我们使用
Binder
来访问我们在服务中声明的方法,并执行以下操作:boolean attachPlayerControlView(PlayerControlView playerControlView) {
if (player != null) {
playerControlView.setPlayer(player);
return true;
}
return false;
}
但是,这对于
MediaBrowserService/ MediaBrowser
框架似乎是不可能的。我检查了此question的答案,这表明使用[sendCommand]是调用自定义方法的一种方法。但这也要求参数是可组合的。总而言之,我的问题是,是否有一种方法可以让
PlayerControlView
访问SimpleExoPlayer
实例,或者在MediaBrowserService
框架下具有另一种方法。非常感谢您的任何回答或评论。
最佳答案
根据我的理解,这是不正确的。您可以随时绑定(bind)到
MediaBrowserService以传统方式使用,即使用IBinder访问服务。 (尽管我不确定这是否是正确的方法,否则我必须在Service中创建一个静态MediaPlayer实例)。
使用MediaPlayer进行视频播放时,我也遇到了类似的问题。我已经使用IBinder绑定(bind)到MediaBrowserService,然后获取了MediaPlayer实例。在您的服务中,提供一种返回对MediaPlayer的引用的方法。像这样的东西:
private MediaPlayer mediaPlayer;
@Override
public IBinder onBind(Intent intent) {
if (intent.getAction().equals("YOUR_INTENT")) {
return new LocalBinder();
}
return super.onBind(intent);
}
public class LocalBinder extends Binder{
public AudioService getService(){
return AudioService.this;
}
}
public MediaPlayer getMediaPlayer() {
return mediaPlayer;
}
在 Activity/fragment 中,然后使用IBinder绑定(bind)到MediaBrowserService。在我的实现中,我使用了MediaPlayer,但是我认为可以将其用于Exoplayer。public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback{
private MediaPlayer mediaPlayer;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private boolean isServiceBounded;
private boolean isSurfaceReady;
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
isServiceBounded = true;
mediaPlayer = ((AudioService)service).getMediaPlayer();
if (isSurfaceReady) {
mediaPlayer.setDisplay(surfaceHolder);
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
isServiceBounded = false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView = findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
bindService(new Intent("YOUR_INTENT"), serviceConnection, BIND_AUTO_CREATE);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
surfaceHolder = holder;
isSurfaceReady = true;
if (mediaPlayer != null) {
mediaPlayer.setDisplay(holder);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
isSurfaceReady = false;
if (mediaPlayer != null) {
mediaPlayer.setDisplay(null);
}
surfaceHolder = null;
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(serviceConnection);
}
}关于android - 具有ExoPlayer和PlayerControlView的MediaBrowserService-如何从UI(PlayerControlView)访问播放器实例?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61017893/