[Android] Audio delay option when audio is routed via BT

Geoffrey Métais git at videolan.org
Wed Aug 3 15:40:04 CEST 2016


vlc-android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Tue Aug  2 14:56:57 2016 +0200| [2ed822f7e5f9f50d656ce4ac112c3fb6d0b2cb85] | committer: Geoffrey Métais

Audio delay option when audio is routed via BT

> https://code.videolan.org/videolan/vlc-android/commit/2ed822f7e5f9f50d656ce4ac112c3fb6d0b2cb85
---

 vlc-android/AndroidManifest.xml                    |  1 +
 vlc-android/res/values/strings.xml                 |  1 +
 .../vlc/gui/video/VideoPlayerActivity.java         | 56 ++++++++++++++++++++--
 3 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/vlc-android/AndroidManifest.xml b/vlc-android/AndroidManifest.xml
index c32260e..78f4aed 100644
--- a/vlc-android/AndroidManifest.xml
+++ b/vlc-android/AndroidManifest.xml
@@ -54,6 +54,7 @@
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+    <uses-permission android:name="android.permission.BLUETOOTH"/>
 
     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
 
diff --git a/vlc-android/res/values/strings.xml b/vlc-android/res/values/strings.xml
index c215cd7..9460855 100644
--- a/vlc-android/res/values/strings.xml
+++ b/vlc-android/res/values/strings.xml
@@ -648,6 +648,7 @@
     <string name="listen">Listen</string>
     <string name="subtitles_download_title">Subs download</string>
     <string name="connecting">Connecting...</string>
+    <string name="save_bluetooth_delay">save delay for bluetooth device</string>
 
     <string-array name="chroma_formats" translatable="false">
         <item>RGB 32-bit</item>
diff --git a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
index 191828e..9b6e224 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
@@ -24,6 +24,8 @@ import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.KeyguardManager;
 import android.app.Presentation;
+import android.bluetooth.BluetoothA2dp;
+import android.bluetooth.BluetoothHeadset;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -49,6 +51,7 @@ import android.preference.PreferenceManager;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
 import android.support.annotation.NonNull;
+import android.support.design.widget.Snackbar;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.content.LocalBroadcastManager;
 import android.support.v4.view.GestureDetectorCompat;
@@ -110,7 +113,6 @@ import org.videolan.vlc.gui.helpers.OnRepeatListener;
 import org.videolan.vlc.gui.helpers.SwipeDragItemTouchHelperCallback;
 import org.videolan.vlc.gui.helpers.UiTools;
 import org.videolan.vlc.gui.preferences.PreferencesActivity;
-import org.videolan.vlc.gui.preferences.PreferencesUi;
 import org.videolan.vlc.gui.tv.audioplayer.AudioPlayerActivity;
 import org.videolan.vlc.interfaces.IPlaybackSettingsController;
 import org.videolan.vlc.media.MediaDatabase;
@@ -130,7 +132,6 @@ import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-import java.io.StreamCorruptedException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Date;
@@ -249,7 +250,8 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
     private int mScreenOrientationLock;
     private ImageView mLock;
     private ImageView mSize;
-    private String KEY_REMAINING_TIME_DISPLAY = "remaining_time_display";;
+    private String KEY_REMAINING_TIME_DISPLAY = "remaining_time_display";
+    private String KEY_BLUETOOTH_DELAY = "key_bluetooth_delay";
 
     @Override
     public boolean onGenericMotionEvent(MotionEvent event) {
@@ -653,6 +655,11 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
         filter.addAction(EXIT_PLAYER);
         LocalBroadcastManager.getInstance(this).registerReceiver(
                 mServiceReceiver, filter);
+        if (mBtReceiver != null) {
+            IntentFilter btFilter = new IntentFilter(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
+            btFilter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
+            registerReceiver(mBtReceiver, btFilter);
+        }
     }
 
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@@ -661,6 +668,8 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
         super.onStop();
         LocalBroadcastManager.getInstance(this).unregisterReceiver(mServiceReceiver);
 
+        if (mBtReceiver != null)
+            unregisterReceiver(mBtReceiver);
         if (mAlertDialog != null && mAlertDialog.isShowing())
             mAlertDialog.dismiss();
         if (!isFinishing() && mService != null && mService.isPlaying() &&
@@ -764,6 +773,8 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
         boolean ratePref = mSettings.getBoolean(PreferencesActivity.KEY_AUDIO_PLAYBACK_SPEED_PERSIST, true);
         mService.setRate(ratePref ? mSettings.getFloat(PreferencesActivity.VIDEO_RATE, 1.0f) : 1.0F, false);
 
+        if (mBtReceiver != null && (mAudioManager.isBluetoothA2dpOn() || mAudioManager.isBluetoothScoOn()))
+            toggleBtDelay(true);
 
         if (mService.hasPlaylist()) {
             mPlaylistPrevious = (ImageView) findViewById(R.id.playlist_previous);
@@ -1342,6 +1353,15 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
     @Override
     public void endPlaybackSetting() {
         mTouchAction = TOUCH_NONE;
+        if (mBtReceiver != null && mPlaybackSetting == DelayState.AUDIO
+                && (mAudioManager.isBluetoothA2dpOn() || mAudioManager.isBluetoothScoOn())) {
+            String msg = getString(R.string.audio_delay) + "\n"
+                    + mService.getAudioDelay() / 1000l
+                    + " ms";
+            Snackbar sb = Snackbar.make(mInfo, msg, Snackbar.LENGTH_LONG);
+            sb.setAction(R.string.save_bluetooth_delay, mBtSaveListener);
+            sb.show();
+        }
         mPlaybackSetting = DelayState.OFF;
         mPlaybackSettingMinus.setOnClickListener(null);
         mPlaybackSettingPlus.setOnClickListener(null);
@@ -3178,6 +3198,36 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
         updateList();
     }
 
+    private BroadcastReceiver mBtReceiver = AndroidUtil.isICSOrLater() ? new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            switch (intent.getAction()) {
+                case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
+                case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
+                    long savedDelay = mSettings.getLong(KEY_BLUETOOTH_DELAY, 0l);
+                    long currentDelay = mService.getAudioDelay();
+                    if (savedDelay != 0l) {
+                        boolean connected = intent.getIntExtra(BluetoothA2dp.EXTRA_STATE, -1) == BluetoothA2dp.STATE_CONNECTED;
+                        if (connected && currentDelay == 0l)
+                            toggleBtDelay(true);
+                        else if (!connected && savedDelay == currentDelay)
+                            toggleBtDelay(false);
+                    }
+            }
+        }
+    } : null;
+
+    private void toggleBtDelay(boolean connected) {
+        mService.setAudioDelay(connected ? mSettings.getLong(KEY_BLUETOOTH_DELAY, 0) : 0l);
+    }
+
+    private OnClickListener mBtSaveListener = new OnClickListener() {
+        @Override
+        public void onClick(View view) {
+            Util.commitPreferences(mSettings.edit().putLong(KEY_BLUETOOTH_DELAY, mService.getAudioDelay()));
+        }
+    };
+
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     private void createPresentation() {
         if (mMediaRouter == null || mEnableCloneMode)



More information about the Android mailing list