- 易迪拓培训,专注于微波、射频、天线设计工程师的培养
蓝牙耳机控制视频快进快退
录入:edatop.com 点击:
[DESCRIPTION]
蓝牙耳机按照google的passthrough_cmd_cb方式回调时,视频播放器需要通过RemoteControlCLIent更新状态给到BT,最终实现蓝牙耳机控制视频的快进快退
[SOLUTION]
Step1: 创建RemoteControlClient对象;
Step2: 借助OnPlaybackPositionUpdateListener来获取BT传过来快进快退后的newpos,并将视频seek到相应的位置;
如上两个步骤实现具体
code:alps/packages/apps/Gallery2/src/com/android/gallery3d/app/MoviePlayer.java
public MoviePlayer(View rootView, final MovieActivity movieActivity,
IMovieItem info,
Bundle savedInstance, boolean canReplay, String cookie) {
....
//added for fast rewind and forward start
//Step1: creat RemoteControlClient object
mAudioManager = (AudioManager)
mContext.getSystEMService(Context.AUDIO_SERVICE);
ComponentName rec = new ComponentName(mContext.getPackageName(),
MediaButtonIntentReceiver.class.getName());
mAudioManager.registerMediaButtonEventReceiver(rec);
Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
i.setComponent(rec);
PendingIntent pi = PendingIntent.getBroADCast(mContext /*context*/,
0 /*requestCode, ignored*/, i /*intent*/, 0 /*flags*/);
mRemoteControlClient = new RemoteControlClient(pi);
//Step2: override callback
int flags = RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE;
mRemoteControlClient.setTransportControlFlags(flags);
mRemoteControlClient.setPlaybackPositionUpdateListener(new
OnPlaybackPositionUpdateListener() {
@Override
public void onPlaybackPositionUpdate(long newpos) {
long cur_pos = mVideoView.getCurrentPosition();
long duration = mVideoView.getDuration();
Log.i(TAG, "onPlaybackPositionUpdate newpos: " + newpos + ", cur_pos: " +
cur_pos + ", duration: " + duration);
if(newpos < 0){
newpos = 0; // play fROM begin
}else if(newpos > duration){
newpos = duration;
}
if(cur_pos - newpos > duration/8){
newpos = cur_pos - duration/8;
}else if(newpos - cur_pos > duration/8){
newpos = cur_pos + duration/8;
}
Log.i(TAG,"newpos: " + newpos);
mVideoView.seekTo((int)newpos);
mRemoteControlClient.setPlaybackState(
cur_pos: RemoteControlClient.PLAYSTATE_REWINDING, newpos, 1.0f);
}
});
//added for fast rewind and forward end
...
}
Step3: AP在开始做渲染的时候,将当前play/pause的状态传给BT
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
...
// / M: add log for performance auto test @{
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
Log.i(TAG,"MoviePlayer.onInfo rendering start setPlaybackState
PLAYSTATE_PLAYING");//added by mtk
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYIN
G,
mVideoView.getCurrentPosition(),1.0f);//added by mtk
...
}
...
}
Step4: AP做了seek动作后,要更新位置给BT;
@Override
public void onSeekEnd(int time, int start, int end) {
if (LOG) {
Log.v(TAG, "onSeekEnd(" + time + ") mDragging=" + mDragging);
}
mDragging = false;
// /M:No need to seek to the same position twice
if (mSeekMovePosition != time) {
// / @}
mVideoView.seekTo(time);
mRemoteControlClient.setPlaybackState(isPlaying() ?
RemoteControlClient.PLAYSTATE_PLAYING
: RemoteControlClient.PLAYSTATE_PAUSED, time, 1.0f);//added by MTK
}
...
}
Step5: AP做了play/pause切换后,要将状态更新给BT
public boolean onKeyDown(int keyCode, KeyEvent event) {
...
switch (keyCode) {
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
if (mVideoView.isPlaying() && mVideoView.canPause()) {
pauseVideo();
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED
,
mVideoView.getCurrentPosition(), 1.0f); //added by MTK
} else {
playVideo();
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYIN
G,
mVideoView.getCurrentPosition(), 1.0f); //added by MTK
}
//set view disabled(play/pause asynchronous processing)
mController.setViewEnabled(false);
return true;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
if (mVideoView.isPlaying() && mVideoView.canPause()) {
pauseVideo();
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED
,
mVideoView.getCurrentPosition(), 1.0f); //added by MTK
//set view disabled(play/pause asynchronous processing)
mController.setViewEnabled(false);
}
return true;
case KeyEvent.KEYCODE_MEDIA_PLAY:
if (!mVideoView.isPlaying()) {
playVideo();
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYIN
G,
mVideoView.getCurrentPosition(), 1.0f); //added by MTK
//set view disabled(play/pause asynchronous processing)
mController.setViewEnabled(false);
}
return true;
...
}
....
}
蓝牙耳机按照google的passthrough_cmd_cb方式回调时,视频播放器需要通过RemoteControlCLIent更新状态给到BT,最终实现蓝牙耳机控制视频的快进快退
[SOLUTION]
Step1: 创建RemoteControlClient对象;
Step2: 借助OnPlaybackPositionUpdateListener来获取BT传过来快进快退后的newpos,并将视频seek到相应的位置;
如上两个步骤实现具体
code:alps/packages/apps/Gallery2/src/com/android/gallery3d/app/MoviePlayer.java
public MoviePlayer(View rootView, final MovieActivity movieActivity,
IMovieItem info,
Bundle savedInstance, boolean canReplay, String cookie) {
....
//added for fast rewind and forward start
//Step1: creat RemoteControlClient object
mAudioManager = (AudioManager)
mContext.getSystEMService(Context.AUDIO_SERVICE);
ComponentName rec = new ComponentName(mContext.getPackageName(),
MediaButtonIntentReceiver.class.getName());
mAudioManager.registerMediaButtonEventReceiver(rec);
Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
i.setComponent(rec);
PendingIntent pi = PendingIntent.getBroADCast(mContext /*context*/,
0 /*requestCode, ignored*/, i /*intent*/, 0 /*flags*/);
mRemoteControlClient = new RemoteControlClient(pi);
//Step2: override callback
int flags = RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE;
mRemoteControlClient.setTransportControlFlags(flags);
mRemoteControlClient.setPlaybackPositionUpdateListener(new
OnPlaybackPositionUpdateListener() {
@Override
public void onPlaybackPositionUpdate(long newpos) {
long cur_pos = mVideoView.getCurrentPosition();
long duration = mVideoView.getDuration();
Log.i(TAG, "onPlaybackPositionUpdate newpos: " + newpos + ", cur_pos: " +
cur_pos + ", duration: " + duration);
if(newpos < 0){
newpos = 0; // play fROM begin
}else if(newpos > duration){
newpos = duration;
}
if(cur_pos - newpos > duration/8){
newpos = cur_pos - duration/8;
}else if(newpos - cur_pos > duration/8){
newpos = cur_pos + duration/8;
}
Log.i(TAG,"newpos: " + newpos);
mVideoView.seekTo((int)newpos);
mRemoteControlClient.setPlaybackState(
cur_pos: RemoteControlClient.PLAYSTATE_REWINDING, newpos, 1.0f);
}
});
//added for fast rewind and forward end
...
}
Step3: AP在开始做渲染的时候,将当前play/pause的状态传给BT
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
...
// / M: add log for performance auto test @{
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
Log.i(TAG,"MoviePlayer.onInfo rendering start setPlaybackState
PLAYSTATE_PLAYING");//added by mtk
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYIN
G,
mVideoView.getCurrentPosition(),1.0f);//added by mtk
...
}
...
}
Step4: AP做了seek动作后,要更新位置给BT;
@Override
public void onSeekEnd(int time, int start, int end) {
if (LOG) {
Log.v(TAG, "onSeekEnd(" + time + ") mDragging=" + mDragging);
}
mDragging = false;
// /M:No need to seek to the same position twice
if (mSeekMovePosition != time) {
// / @}
mVideoView.seekTo(time);
mRemoteControlClient.setPlaybackState(isPlaying() ?
RemoteControlClient.PLAYSTATE_PLAYING
: RemoteControlClient.PLAYSTATE_PAUSED, time, 1.0f);//added by MTK
}
...
}
Step5: AP做了play/pause切换后,要将状态更新给BT
public boolean onKeyDown(int keyCode, KeyEvent event) {
...
switch (keyCode) {
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
if (mVideoView.isPlaying() && mVideoView.canPause()) {
pauseVideo();
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED
,
mVideoView.getCurrentPosition(), 1.0f); //added by MTK
} else {
playVideo();
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYIN
G,
mVideoView.getCurrentPosition(), 1.0f); //added by MTK
}
//set view disabled(play/pause asynchronous processing)
mController.setViewEnabled(false);
return true;
case KeyEvent.KEYCODE_MEDIA_PAUSE:
if (mVideoView.isPlaying() && mVideoView.canPause()) {
pauseVideo();
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED
,
mVideoView.getCurrentPosition(), 1.0f); //added by MTK
//set view disabled(play/pause asynchronous processing)
mController.setViewEnabled(false);
}
return true;
case KeyEvent.KEYCODE_MEDIA_PLAY:
if (!mVideoView.isPlaying()) {
playVideo();
mRemoteControlClient.setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYIN
G,
mVideoView.getCurrentPosition(), 1.0f); //added by MTK
//set view disabled(play/pause asynchronous processing)
mController.setViewEnabled(false);
}
return true;
...
}
....
}
申明:网友回复良莠不齐,仅供参考。如需专业帮助,请学习易迪拓培训专家讲授的ADS视频培训课程。
上一篇:ADS数据无法通信,求资深工程师指教
下一篇:ADS2013.06版安装的问题
ADS培训课程推荐详情>>
国内最全面、最专业的Agilent ADS培训课程,可以帮助您从零开始,全面系统学习ADS设计应用【More..】
- Agilent ADS教学培训课程套装
- 两周学会ADS2011、ADS2013视频教程
- ADS2012、ADS2013射频电路设计详解
- ADS高低阻抗线微带滤波器设计培训教程
- ADS混频器仿真分析实例视频培训课程
- ADS Momentum电磁仿真设计视频课程
- ADS射频电路与通信系统设计高级培训
- ADS Layout和电磁仿真设计培训视频
- ADS Workspace and Simulators Training Course
- ADS Circuit Simulation Training Course
- ADS Layout and EM Simulation Training Course
- Agilent ADS 内部原版培训教材合集