Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Casanowow Life for love
VLC-Android
Commits
0aa76951
Commit
0aa76951
authored
Apr 16, 2018
by
Geoffrey Métais
Browse files
Extract audio focus mgmt from PlaybackService
parent
41ab7aef
Changes
2
Hide whitespace changes
Inline
Side-by-side
vlc-android/src/org/videolan/vlc/PlaybackService.kt
View file @
0aa76951
...
...
@@ -83,12 +83,12 @@ class PlaybackService : MediaBrowserServiceCompat() {
private
val
callbacks
=
ArrayList
<
Callback
>()
private
var
detectHeadset
=
true
private
lateinit
var
wakeLock
:
PowerManager
.
WakeLock
private
val
audioFocusHelper
by
lazy
{
VLCAudioFocusHelper
(
this
)
}
// Playback management
internal
lateinit
var
mediaSession
:
MediaSessionCompat
private
var
widget
=
0
private
var
hasAudioFocus
=
false
/**
* Last widget position update timestamp
*/
...
...
@@ -97,13 +97,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
internal
var
libraryReceiver
:
MedialibraryReceiver
?
=
null
private
val
audioFocusListener
=
createOnAudioFocusChangeListener
()
@Volatile
private
var
lossTransient
=
false
private
lateinit
var
audioManager
:
AudioManager
private
val
receiver
=
object
:
BroadcastReceiver
()
{
private
var
wasPlaying
=
false
override
fun
onReceive
(
context
:
Context
,
intent
:
Intent
)
{
...
...
@@ -171,7 +164,7 @@ class PlaybackService : MediaBrowserServiceCompat() {
if
(
BuildConfig
.
DEBUG
)
Log
.
i
(
TAG
,
"MediaPlayer.Event.Playing"
)
executeUpdate
()
publishState
()
changeAudioFocus
(
true
)
audioFocusHelper
.
changeAudioFocus
(
true
)
if
(!
wakeLock
.
isHeld
)
wakeLock
.
acquire
()
if
(!
keyguardManager
.
inKeyguardRestrictedInputMode
()
&&
!
playlistManager
.
videoBackground
...
...
@@ -567,83 +560,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
return
playlistManager
.
player
.
getVout
()
}
private
fun
createOnAudioFocusChangeListener
():
OnAudioFocusChangeListener
{
return
object
:
OnAudioFocusChangeListener
{
internal
var
audioDuckLevel
=
-
1
private
var
mLossTransientVolume
=
-
1
private
var
wasPlaying
=
false
override
fun
onAudioFocusChange
(
focusChange
:
Int
)
{
/*
* Pause playback during alerts and notifications
*/
when
(
focusChange
)
{
AudioManager
.
AUDIOFOCUS_LOSS
->
{
if
(
BuildConfig
.
DEBUG
)
Log
.
i
(
TAG
,
"AUDIOFOCUS_LOSS"
)
// Pause playback
changeAudioFocus
(
false
)
pause
()
}
AudioManager
.
AUDIOFOCUS_LOSS_TRANSIENT
->
{
if
(
BuildConfig
.
DEBUG
)
Log
.
i
(
TAG
,
"AUDIOFOCUS_LOSS_TRANSIENT"
)
// Pause playback
pausePlayback
()
}
AudioManager
.
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
->
{
if
(
BuildConfig
.
DEBUG
)
Log
.
i
(
TAG
,
"AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK"
)
// Lower the volume
if
(
isPlaying
)
{
if
(
AndroidDevices
.
isAmazon
)
{
pausePlayback
()
}
else
if
(
settings
.
getBoolean
(
"audio_ducking"
,
true
))
{
val
volume
=
if
(
AndroidDevices
.
isAndroidTv
)
volume
else
audioManager
.
getStreamVolume
(
AudioManager
.
STREAM_MUSIC
)
if
(
audioDuckLevel
==
-
1
)
audioDuckLevel
=
if
(
AndroidDevices
.
isAndroidTv
)
50
else
audioManager
.
getStreamMaxVolume
(
AudioManager
.
STREAM_MUSIC
)
/
5
if
(
volume
>
audioDuckLevel
)
{
mLossTransientVolume
=
volume
if
(
AndroidDevices
.
isAndroidTv
)
setVolume
(
audioDuckLevel
)
else
audioManager
.
setStreamVolume
(
AudioManager
.
STREAM_MUSIC
,
audioDuckLevel
,
0
)
}
}
}
}
AudioManager
.
AUDIOFOCUS_GAIN
->
{
if
(
BuildConfig
.
DEBUG
)
Log
.
i
(
TAG
,
"AUDIOFOCUS_GAIN: "
)
// Resume playback
if
(
mLossTransientVolume
!=
-
1
)
{
if
(
AndroidDevices
.
isAndroidTv
)
setVolume
(
mLossTransientVolume
)
else
audioManager
.
setStreamVolume
(
AudioManager
.
STREAM_MUSIC
,
mLossTransientVolume
,
0
)
mLossTransientVolume
=
-
1
}
if
(
lossTransient
)
{
if
(
wasPlaying
&&
settings
.
getBoolean
(
"resume_playback"
,
true
))
play
()
lossTransient
=
false
}
}
}
}
private
fun
pausePlayback
()
{
if
(
lossTransient
)
return
lossTransient
=
true
wasPlaying
=
isPlaying
if
(
wasPlaying
)
pause
()
}
}
}
private
fun
sendStartSessionIdIntent
()
{
val
sessionId
=
VLCOptions
.
getAudiotrackSessionId
()
if
(
sessionId
==
0
)
return
...
...
@@ -666,26 +582,6 @@ class PlaybackService : MediaBrowserServiceCompat() {
sendBroadcast
(
intent
)
}
private
fun
changeAudioFocus
(
acquire
:
Boolean
)
{
if
(!
this
::
audioManager
.
isInitialized
)
audioManager
=
getSystemService
(
Context
.
AUDIO_SERVICE
)
as
?
AudioManager
?:
return
if
(
acquire
&&
!
hasRenderer
())
{
if
(!
hasAudioFocus
)
{
val
result
=
audioManager
.
requestAudioFocus
(
audioFocusListener
,
AudioManager
.
STREAM_MUSIC
,
AudioManager
.
AUDIOFOCUS_GAIN
)
if
(
result
==
AudioManager
.
AUDIOFOCUS_REQUEST_GRANTED
)
{
audioManager
.
setParameters
(
"bgm_state=true"
)
hasAudioFocus
=
true
}
}
}
else
if
(
hasAudioFocus
)
{
audioManager
.
abandonAudioFocus
(
audioFocusListener
)
audioManager
.
setParameters
(
"bgm_state=false"
)
hasAudioFocus
=
false
}
}
fun
setBenchmark
()
{
playlistManager
.
isBenchmark
=
true
}
...
...
@@ -701,7 +597,7 @@ class PlaybackService : MediaBrowserServiceCompat() {
fun
onPlaybackStopped
(
systemExit
:
Boolean
)
{
if
(!
systemExit
)
hideNotification
(
VLCApplication
.
isForeground
())
if
(
wakeLock
.
isHeld
)
wakeLock
.
release
()
changeAudioFocus
(
false
)
audioFocusHelper
.
changeAudioFocus
(
false
)
medialibrary
.
resumeBackgroundOperations
()
// We must publish state before resetting mCurrentIndex
publishState
()
...
...
@@ -786,7 +682,7 @@ class PlaybackService : MediaBrowserServiceCompat() {
mw
.
hasFlag
(
MediaWrapper
.
MEDIA_FORCE_AUDIO
),
title
,
artist
,
album
,
cover
,
playing
,
sessionToken
,
sessionPendingIntent
)
if
(
isPlayingPopup
)
return
@launch
if
(!
AndroidUtil
.
isLolliPopOrLater
||
playing
||
lossTransient
)
{
if
(!
AndroidUtil
.
isLolliPopOrLater
||
playing
||
audioFocusHelper
.
lossTransient
)
{
if
(!
isForeground
)
{
this
@PlaybackService
.
startForeground
(
3
,
notification
)
isForeground
=
true
...
...
@@ -1415,9 +1311,8 @@ class PlaybackService : MediaBrowserServiceCompat() {
VideoPlayerActivity
.
startOpened
(
VLCApplication
.
getAppContext
(),
playlistManager
.
getCurrentMedia
()
!!
.
uri
,
playlistManager
.
currentIndex
)
playlistManager
.
setRenderer
(
item
)
if
(!
wasOnRenderer
&&
item
!=
null
)
changeAudioFocus
(
false
)
else
if
(
wasOnRenderer
&&
item
==
null
&&
isPlaying
)
changeAudioFocus
(
true
)
if
(!
wasOnRenderer
&&
item
!=
null
)
audioFocusHelper
.
changeAudioFocus
(
false
)
else
if
(
wasOnRenderer
&&
item
==
null
&&
isPlaying
)
audioFocusHelper
.
changeAudioFocus
(
true
)
}
@MainThread
...
...
vlc-android/src/org/videolan/vlc/util/VLCAudioFocusHelper.kt
0 → 100644
View file @
0aa76951
/*
* ************************************************************************
* VLCAudioFocusHelper.kt
* *************************************************************************
* Copyright © 2018 VLC authors and VideoLAN
* Author: Geoffrey Métais
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*
* *************************************************************************
*/
package
org.videolan.vlc.util
import
android.content.Context
import
android.media.AudioManager
import
android.util.Log
import
org.videolan.vlc.BuildConfig
import
org.videolan.vlc.PlaybackService
private
const
val
TAG
=
"VLCAudioFocusHelper"
class
VLCAudioFocusHelper
(
private
val
service
:
PlaybackService
)
{
private
lateinit
var
audioManager
:
AudioManager
private
var
hasAudioFocus
=
false
@Volatile
internal
var
lossTransient
=
false
private
val
audioFocusListener
=
createOnAudioFocusChangeListener
()
internal
fun
changeAudioFocus
(
acquire
:
Boolean
)
{
if
(!
this
::
audioManager
.
isInitialized
)
audioManager
=
service
.
getSystemService
(
Context
.
AUDIO_SERVICE
)
as
?
AudioManager
?:
return
if
(
acquire
&&
!
service
.
hasRenderer
())
{
if
(!
hasAudioFocus
)
{
val
result
=
audioManager
.
requestAudioFocus
(
audioFocusListener
,
AudioManager
.
STREAM_MUSIC
,
AudioManager
.
AUDIOFOCUS_GAIN
)
if
(
result
==
AudioManager
.
AUDIOFOCUS_REQUEST_GRANTED
)
{
audioManager
.
setParameters
(
"bgm_state=true"
)
hasAudioFocus
=
true
}
}
}
else
if
(
hasAudioFocus
)
{
audioManager
.
abandonAudioFocus
(
audioFocusListener
)
audioManager
.
setParameters
(
"bgm_state=false"
)
hasAudioFocus
=
false
}
}
private
fun
createOnAudioFocusChangeListener
():
AudioManager
.
OnAudioFocusChangeListener
{
return
object
:
AudioManager
.
OnAudioFocusChangeListener
{
internal
var
audioDuckLevel
=
-
1
private
var
mLossTransientVolume
=
-
1
private
var
wasPlaying
=
false
override
fun
onAudioFocusChange
(
focusChange
:
Int
)
{
/*
* Pause playback during alerts and notifications
*/
when
(
focusChange
)
{
AudioManager
.
AUDIOFOCUS_LOSS
->
{
if
(
BuildConfig
.
DEBUG
)
Log
.
i
(
TAG
,
"AUDIOFOCUS_LOSS"
)
// Pause playback
changeAudioFocus
(
false
)
service
.
pause
()
}
AudioManager
.
AUDIOFOCUS_LOSS_TRANSIENT
->
{
if
(
BuildConfig
.
DEBUG
)
Log
.
i
(
TAG
,
"AUDIOFOCUS_LOSS_TRANSIENT"
)
// Pause playback
pausePlayback
()
}
AudioManager
.
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
->
{
if
(
BuildConfig
.
DEBUG
)
Log
.
i
(
TAG
,
"AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK"
)
// Lower the volume
if
(
service
.
isPlaying
)
{
if
(
AndroidDevices
.
isAmazon
)
{
pausePlayback
()
}
else
if
(
service
.
settings
.
getBoolean
(
"audio_ducking"
,
true
))
{
val
volume
=
if
(
AndroidDevices
.
isAndroidTv
)
service
.
volume
else
audioManager
.
getStreamVolume
(
AudioManager
.
STREAM_MUSIC
)
if
(
audioDuckLevel
==
-
1
)
audioDuckLevel
=
if
(
AndroidDevices
.
isAndroidTv
)
50
else
audioManager
.
getStreamMaxVolume
(
AudioManager
.
STREAM_MUSIC
)
/
5
if
(
volume
>
audioDuckLevel
)
{
mLossTransientVolume
=
volume
if
(
AndroidDevices
.
isAndroidTv
)
service
.
setVolume
(
audioDuckLevel
)
else
audioManager
.
setStreamVolume
(
AudioManager
.
STREAM_MUSIC
,
audioDuckLevel
,
0
)
}
}
}
}
AudioManager
.
AUDIOFOCUS_GAIN
->
{
if
(
BuildConfig
.
DEBUG
)
Log
.
i
(
TAG
,
"AUDIOFOCUS_GAIN: "
)
// Resume playback
if
(
mLossTransientVolume
!=
-
1
)
{
if
(
AndroidDevices
.
isAndroidTv
)
service
.
setVolume
(
mLossTransientVolume
)
else
audioManager
.
setStreamVolume
(
AudioManager
.
STREAM_MUSIC
,
mLossTransientVolume
,
0
)
mLossTransientVolume
=
-
1
}
if
(
lossTransient
)
{
if
(
wasPlaying
&&
service
.
settings
.
getBoolean
(
"resume_playback"
,
true
))
service
.
play
()
lossTransient
=
false
}
}
}
}
private
fun
pausePlayback
()
{
if
(
lossTransient
)
return
lossTransient
=
true
wasPlaying
=
service
.
isPlaying
if
(
wasPlaying
)
service
.
pause
()
}
}
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment