Merge pull request #1385 from prathameshmm02/dev

Playback speed and pitch fix
This commit is contained in:
Daksh P. Jain 2022-06-22 11:53:47 +05:30 committed by GitHub
commit 10367f64de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 86 additions and 53 deletions

View file

@ -30,7 +30,6 @@ android {
} }
buildTypes { buildTypes {
release { release {
versionNameSuffix "_" + getDate()
shrinkResources true shrinkResources true
minifyEnabled true minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
@ -88,10 +87,6 @@ static def getProperty(Properties properties, String name) {
return properties.getProperty(name) ?: "$name missing" return properties.getProperty(name) ?: "$name missing"
} }
static def getDate() {
new Date().format('MMddyyyyss')
}
dependencies { dependencies {
implementation project(':appthemehelper') implementation project(':appthemehelper')
implementation "androidx.gridlayout:gridlayout:1.0.0" implementation "androidx.gridlayout:gridlayout:1.0.0"

View file

@ -31,7 +31,7 @@ import java.lang.ref.WeakReference
* Created by Beesham Sarendranauth (Beesham) * Created by Beesham Sarendranauth (Beesham)
*/ */
class AutoMusicProvider( class AutoMusicProvider(
val mContext: Context, private val mContext: Context,
private val songsRepository: SongRepository, private val songsRepository: SongRepository,
private val albumsRepository: AlbumRepository, private val albumsRepository: AlbumRepository,
private val artistsRepository: ArtistRepository, private val artistsRepository: ArtistRepository,
@ -138,7 +138,7 @@ class AutoMusicProvider(
topPlayedRepository.notRecentlyPlayedTracks().take(8) topPlayedRepository.notRecentlyPlayedTracks().take(8)
} }
else -> { else -> {
emptyList() emptyList()
} }
} }
songs.forEach { song -> songs.forEach { song ->

View file

@ -60,8 +60,7 @@ class SongShareDialog : DialogFragment() {
0 -> { 0 -> {
startActivity(Intent.createChooser(song?.let { startActivity(Intent.createChooser(song?.let {
MusicUtil.createShareSongFileIntent( MusicUtil.createShareSongFileIntent(
it, requireContext(), it
requireContext()
) )
}, null)) }, null))
} }

View file

@ -64,7 +64,7 @@ object SongMenuHelper : KoinComponent {
R.id.action_share -> { R.id.action_share -> {
activity.startActivity( activity.startActivity(
Intent.createChooser( Intent.createChooser(
MusicUtil.createShareSongFileIntent(song, activity), MusicUtil.createShareSongFileIntent(activity, song),
null null
) )
) )

View file

@ -14,6 +14,7 @@
*/ */
package code.name.monkey.retromusic.helper.menu package code.name.monkey.retromusic.helper.menu
import android.content.Intent
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
@ -21,6 +22,7 @@ import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.RealRepository import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.util.MusicUtil
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -53,6 +55,15 @@ object SongsMenuHelper : KoinComponent {
} }
return true return true
} }
R.id.action_share -> {
activity.startActivity(
Intent.createChooser(
MusicUtil.createShareMultipleSongIntent(activity, songs),
null
)
)
return true
}
R.id.action_delete_from_device -> { R.id.action_delete_from_device -> {
DeleteSongsDialog.create(songs) DeleteSongsDialog.create(songs)
.show(activity.supportFragmentManager, "DELETE_SONGS") .show(activity.supportFragmentManager, "DELETE_SONGS")

View file

@ -7,16 +7,21 @@ import android.content.IntentFilter
import android.media.AudioAttributes import android.media.AudioAttributes
import android.media.AudioManager import android.media.AudioManager
import android.media.MediaPlayer import android.media.MediaPlayer
import android.media.PlaybackParams
import android.os.StrictMode
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.media.AudioAttributesCompat import androidx.media.AudioAttributesCompat
import androidx.media.AudioFocusRequestCompat import androidx.media.AudioFocusRequestCompat
import androidx.media.AudioManagerCompat import androidx.media.AudioManagerCompat
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.showToast import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.service.playback.Playback import code.name.monkey.retromusic.service.playback.Playback
import code.name.monkey.retromusic.util.PreferenceUtil.isAudioFocusEnabled import code.name.monkey.retromusic.util.PreferenceUtil.isAudioFocusEnabled
import code.name.monkey.retromusic.util.PreferenceUtil.playbackPitch
import code.name.monkey.retromusic.util.PreferenceUtil.playbackSpeed
abstract class LocalPlayback(val context: Context) : Playback, MediaPlayer.OnErrorListener, abstract class LocalPlayback(val context: Context) : Playback, MediaPlayer.OnErrorListener,
MediaPlayer.OnCompletionListener { MediaPlayer.OnCompletionListener {
@ -121,11 +126,16 @@ abstract class LocalPlayback(val context: Context) : Playback, MediaPlayer.OnErr
} else { } else {
player.setDataSource(path) player.setDataSource(path)
} }
player.setAudioAttributes(AudioAttributes.Builder() player.setAudioAttributes(
.setUsage(AudioAttributes.USAGE_MEDIA) AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setUsage(AudioAttributes.USAGE_MEDIA)
.build() .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
) )
if (VersionUtils.hasMarshmallow())
player.playbackParams =
PlaybackParams().setSpeed(playbackSpeed).setPitch(playbackPitch)
player.setOnPreparedListener { player.setOnPreparedListener {
player.setOnPreparedListener(null) player.setOnPreparedListener(null)
completion(true) completion(true)

View file

@ -23,6 +23,7 @@ import code.name.monkey.retromusic.extensions.uri
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.playback.Playback.PlaybackCallbacks import code.name.monkey.retromusic.service.playback.Playback.PlaybackCallbacks
import code.name.monkey.retromusic.util.PreferenceUtil.isGapLessPlayback import code.name.monkey.retromusic.util.PreferenceUtil.isGapLessPlayback
import code.name.monkey.retromusic.util.logE
/** /**
* @author Andrew Neal, Karim Abou Zeid (kabouzeid) * @author Andrew Neal, Karim Abou Zeid (kabouzeid)
@ -141,9 +142,7 @@ class MultiPlayer(context: Context) : LocalPlayback(context) {
override fun release() { override fun release() {
stop() stop()
mCurrentMediaPlayer.release() mCurrentMediaPlayer.release()
if (mNextMediaPlayer != null) { mNextMediaPlayer?.release()
mNextMediaPlayer?.release()
}
} }
/** /**
@ -249,7 +248,7 @@ class MultiPlayer(context: Context) : LocalPlayback(context) {
mCurrentMediaPlayer = MediaPlayer() mCurrentMediaPlayer = MediaPlayer()
mCurrentMediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK) mCurrentMediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK)
context.showToast(R.string.unplayable_file) context.showToast(R.string.unplayable_file)
Log.e(TAG, what.toString() + extra) logE(what.toString() + extra)
return false return false
} }
@ -260,9 +259,9 @@ class MultiPlayer(context: Context) : LocalPlayback(context) {
mCurrentMediaPlayer = mNextMediaPlayer!! mCurrentMediaPlayer = mNextMediaPlayer!!
isInitialized = true isInitialized = true
mNextMediaPlayer = null mNextMediaPlayer = null
if (callbacks != null) callbacks?.onTrackWentToNext() callbacks?.onTrackWentToNext()
} else { } else {
if (callbacks != null) callbacks?.onTrackEnded() callbacks?.onTrackEnded()
} }
} }
@ -270,6 +269,7 @@ class MultiPlayer(context: Context) : LocalPlayback(context) {
override fun setPlaybackSpeedPitch(speed: Float, pitch: Float) { override fun setPlaybackSpeedPitch(speed: Float, pitch: Float) {
mCurrentMediaPlayer.setPlaybackSpeedPitch(speed, pitch) mCurrentMediaPlayer.setPlaybackSpeedPitch(speed, pitch)
mNextMediaPlayer?.setPlaybackSpeedPitch(speed, pitch)
} }
companion object { companion object {

View file

@ -18,7 +18,6 @@ import android.app.NotificationManager
import android.app.PendingIntent import android.app.PendingIntent
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.bluetooth.BluetoothDevice import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothDevice.EXTRA_DEVICE
import android.content.* import android.content.*
import android.content.SharedPreferences.OnSharedPreferenceChangeListener import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.content.pm.ServiceInfo import android.content.pm.ServiceInfo
@ -224,14 +223,15 @@ class MusicService : MediaBrowserServiceCompat(),
var shuffleMode = 0 var shuffleMode = 0
private val songPlayCountHelper = SongPlayCountHelper() private val songPlayCountHelper = SongPlayCountHelper()
private val bluetoothReceiver = object : BroadcastReceiver() { private val bluetoothReceiver: BroadcastReceiver = object : BroadcastReceiver() {
@SuppressLint("MissingPermission")
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
val action = intent.action val action = intent.action
val extra = intent.getParcelableExtra<BluetoothDevice>(EXTRA_DEVICE)!!
if (action != null) { if (action != null) {
if (BluetoothDevice.ACTION_ACL_CONNECTED == action && isBluetoothSpeaker) { if (BluetoothDevice.ACTION_ACL_CONNECTED == action && isBluetoothSpeaker) {
if (extra.type == BluetoothDevice.DEVICE_TYPE_CLASSIC) play() @Suppress("Deprecation")
if (getSystemService<AudioManager>()!!.isBluetoothA2dpOn) {
play()
}
} }
} }
} }
@ -591,16 +591,9 @@ class MusicService : MediaBrowserServiceCompat(),
* By default return the browsable root. Treat the EXTRA_RECENT flag as a special case * By default return the browsable root. Treat the EXTRA_RECENT flag as a special case
* and return the recent root instead. * and return the recent root instead.
*/ */
var isRecentRequest = false val isRecentRequest = rootHints?.getBoolean(BrowserRoot.EXTRA_RECENT) ?: false
if (rootHints != null) { val browserRootPath =
isRecentRequest = if (isRecentRequest) AutoMediaIDHelper.RECENT_ROOT else AutoMediaIDHelper.MEDIA_ID_ROOT
rootHints.getBoolean(BrowserRoot.EXTRA_RECENT)
}
val browserRootPath = if (isRecentRequest) {
AutoMediaIDHelper.RECENT_ROOT
} else {
AutoMediaIDHelper.MEDIA_ID_ROOT
}
BrowserRoot(browserRootPath, null) BrowserRoot(browserRootPath, null)
} }
} }
@ -974,6 +967,7 @@ class MusicService : MediaBrowserServiceCompat(),
intent.putExtra("position", songProgressMillis.toLong()) intent.putExtra("position", songProgressMillis.toLong())
intent.putExtra("playing", isPlaying) intent.putExtra("playing", isPlaying)
intent.putExtra("scrobbling_source", RETRO_MUSIC_PACKAGE_NAME) intent.putExtra("scrobbling_source", RETRO_MUSIC_PACKAGE_NAME)
@Suppress("Deprecation")
sendStickyBroadcast(intent) sendStickyBroadcast(intent)
} }

View file

@ -6,8 +6,6 @@ import android.media.audiofx.AudioEffect
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.playback.Playback import code.name.monkey.retromusic.service.playback.Playback
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.PreferenceUtil.playbackPitch
import code.name.monkey.retromusic.util.PreferenceUtil.playbackSpeed
class PlaybackManager(val context: Context) { class PlaybackManager(val context: Context) {
@ -35,9 +33,6 @@ class PlaybackManager(val context: Context) {
val isPlaying: Boolean val isPlaying: Boolean
get() = playback != null && playback!!.isPlaying get() = playback != null && playback!!.isPlaying
private val shouldSetSpeed: Boolean
get() = !(playbackSpeed == 1f && playbackPitch == 1f)
init { init {
playback = createLocalPlayback() playback = createLocalPlayback()
} }
@ -61,9 +56,6 @@ class PlaybackManager(val context: Context) {
AudioFader.startFadeAnimator(playback!!, true) AudioFader.startFadeAnimator(playback!!, true)
} }
} }
if (shouldSetSpeed) {
playback?.setPlaybackSpeedPitch(playbackSpeed, playbackPitch)
}
playback?.start() playback?.start()
} }
} }

View file

@ -41,23 +41,49 @@ import java.util.regex.Pattern
object MusicUtil : KoinComponent { object MusicUtil : KoinComponent {
fun createShareSongFileIntent(song: Song, context: Context): Intent { fun createShareSongFileIntent(context: Context, song: Song): Intent {
return Intent().apply { return Intent().apply {
action = Intent.ACTION_SEND action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, try { putExtra(
FileProvider.getUriForFile( Intent.EXTRA_STREAM, try {
context, FileProvider.getUriForFile(
context.applicationContext.packageName, context,
File(song.data) context.applicationContext.packageName,
) File(song.data)
} catch (e: IllegalArgumentException) { )
getSongFileUri(song.id) } catch (e: IllegalArgumentException) {
}) getSongFileUri(song.id)
}
)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
type = "audio/*" type = "audio/*"
} }
} }
fun createShareMultipleSongIntent(context: Context, songs: List<Song>): Intent {
return Intent().apply {
action = Intent.ACTION_SEND_MULTIPLE
type = "audio/*"
val files = ArrayList<Uri>()
for (song in songs) {
files.add(
try {
FileProvider.getUriForFile(
context,
context.applicationContext.packageName,
File(song.data)
)
} catch (e: IllegalArgumentException) {
getSongFileUri(song.id)
}
)
}
putParcelableArrayListExtra(Intent.EXTRA_STREAM, files)
}
}
fun buildInfoString(string1: String?, string2: String?): String { fun buildInfoString(string1: String?, string2: String?): String {
if (string1.isNullOrEmpty()) { if (string1.isNullOrEmpty()) {
return if (string2.isNullOrEmpty()) "" else string2 return if (string2.isNullOrEmpty()) "" else string2

View file

@ -20,6 +20,12 @@
android:title="@string/action_add_to_playlist" android:title="@string/action_add_to_playlist"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item
android:id="@+id/action_share"
android:icon="@drawable/ic_share"
android:title="@string/action_share"
app:showAsAction="ifRoom" />
<item <item
android:id="@+id/action_delete_from_device" android:id="@+id/action_delete_from_device"
android:icon="@drawable/ic_delete" android:icon="@drawable/ic_delete"