mirror of
https://github.com/gedoor/legado.git
synced 2024-08-30 09:23:26 +08:00
commit
2f026e5ffb
@ -179,8 +179,15 @@ dependencies {
|
||||
|
||||
//media
|
||||
implementation("androidx.media:media:1.6.0")
|
||||
implementation("com.google.android.exoplayer:exoplayer-core:$exoplayer_version")
|
||||
implementation("com.google.android.exoplayer:extension-okhttp:$exoplayer_version")
|
||||
// For media playback using ExoPlayer
|
||||
implementation "androidx.media3:media3-exoplayer:$media3_version"
|
||||
// For loading data using the OkHttp network stack
|
||||
implementation "androidx.media3:media3-datasource-okhttp:$media3_version"
|
||||
// For exposing and controlling media sessions
|
||||
//implementation "androidx.media3:media3-session:$media3_version"
|
||||
|
||||
// implementation("com.google.android.exoplayer:exoplayer-core:$exoplayer_version")
|
||||
// implementation("com.google.android.exoplayer:extension-okhttp:$exoplayer_version")
|
||||
|
||||
//Splitties
|
||||
implementation("com.louiscad.splitties:splitties-appctx:$splitties_version")
|
||||
|
2
app/proguard-rules.pro
vendored
2
app/proguard-rules.pro
vendored
@ -239,7 +239,7 @@
|
||||
}
|
||||
|
||||
## ExoPlayer 反射设置ua 保证该私有变量不被混淆
|
||||
-keepclassmembers class com.google.android.exoplayer2.upstream.cache.CacheDataSource$Factory {
|
||||
-keepclassmembers class androidx.media3.datasource.cache.CacheDataSource$Factory {
|
||||
*** upstreamDataSourceFactory;
|
||||
}
|
||||
## ExoPlayer 如果还不能播放就取消注释这个
|
||||
|
@ -1,9 +1,9 @@
|
||||
package io.legado.app.lib.cronet
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Build
|
||||
import androidx.annotation.Keep
|
||||
import androidx.annotation.RequiresApi
|
||||
import io.legado.app.utils.DebugLog
|
||||
import okhttp3.Call
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
@ -12,6 +12,7 @@ import java.io.IOException
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@SuppressLint("ObsoleteSdkInt")
|
||||
@Keep
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
class NewCallBack(originalRequest: Request, mCall: Call) : AbsCallBack(originalRequest, mCall) {
|
||||
|
@ -1,35 +1,79 @@
|
||||
package io.legado.app.help.exoplayer
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.google.android.exoplayer2.database.StandaloneDatabaseProvider
|
||||
import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource
|
||||
import com.google.android.exoplayer2.offline.DefaultDownloaderFactory
|
||||
import com.google.android.exoplayer2.offline.DownloadRequest
|
||||
import com.google.android.exoplayer2.offline.DownloaderFactory
|
||||
import com.google.android.exoplayer2.source.MediaSource
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource
|
||||
import com.google.android.exoplayer2.upstream.DataSource
|
||||
import com.google.android.exoplayer2.upstream.FileDataSource
|
||||
import com.google.android.exoplayer2.upstream.cache.*
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.database.StandaloneDatabaseProvider
|
||||
import androidx.media3.datasource.DataSource
|
||||
import androidx.media3.datasource.FileDataSource
|
||||
import androidx.media3.datasource.ResolvingDataSource
|
||||
import androidx.media3.datasource.cache.Cache
|
||||
import androidx.media3.datasource.cache.CacheDataSink
|
||||
import androidx.media3.datasource.cache.CacheDataSource
|
||||
import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor
|
||||
import androidx.media3.datasource.cache.SimpleCache
|
||||
import androidx.media3.datasource.okhttp.OkHttpDataSource
|
||||
import androidx.media3.exoplayer.DefaultLoadControl
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
import androidx.media3.exoplayer.offline.DefaultDownloaderFactory
|
||||
import androidx.media3.exoplayer.offline.DownloadRequest
|
||||
import androidx.media3.exoplayer.offline.DownloaderFactory
|
||||
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import io.legado.app.help.http.okHttpClient
|
||||
import okhttp3.CacheControl
|
||||
import splitties.init.appCtx
|
||||
import java.io.File
|
||||
import java.lang.reflect.Type
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
||||
@SuppressLint("UnsafeOptInUsageError")
|
||||
object ExoPlayerHelper {
|
||||
|
||||
fun createMediaSource(
|
||||
uri: Uri,
|
||||
defaultRequestProperties: Map<String, String>
|
||||
): MediaSource {
|
||||
val mediaItem = MediaItem.fromUri(uri)
|
||||
val mediaSourceFactory = ProgressiveMediaSource.Factory(
|
||||
cacheDataSourceFactory.setDefaultRequestProperties(defaultRequestProperties)
|
||||
private const val SPLIT_TAG = "\uD83D\uDEA7"
|
||||
|
||||
private val gson by lazy {
|
||||
GsonBuilder().create()
|
||||
}
|
||||
private val mapType by lazy {
|
||||
val type: Type = object : TypeToken<Map<String?, String?>?>() {}.type
|
||||
type
|
||||
}
|
||||
|
||||
// fun createMediaSource(
|
||||
// uri: Uri,
|
||||
// defaultRequestProperties: Map<String, String>
|
||||
// ): MediaSource {
|
||||
// val mediaItem = MediaItem.fromUri(uri)
|
||||
// val mediaSourceFactory = ProgressiveMediaSource.Factory(
|
||||
// cacheDataSourceFactory.setDefaultRequestProperties(defaultRequestProperties)
|
||||
// )
|
||||
// return mediaSourceFactory.createMediaSource(mediaItem)
|
||||
// }
|
||||
|
||||
fun createMediaItem(url: String, headers: Map<String, String>): MediaItem {
|
||||
val formatUrl = url + SPLIT_TAG + gson.toJson(headers, mapType)
|
||||
return MediaItem.Builder().setUri(formatUrl).build()
|
||||
}
|
||||
|
||||
fun createExoPlayer(context: Context): ExoPlayer {
|
||||
return ExoPlayer.Builder(context).setLoadControl(
|
||||
DefaultLoadControl.Builder().setBufferDurationsMs(
|
||||
DefaultLoadControl.DEFAULT_MIN_BUFFER_MS,
|
||||
DefaultLoadControl.DEFAULT_MAX_BUFFER_MS,
|
||||
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS / 10,
|
||||
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS / 10
|
||||
).build()
|
||||
|
||||
)
|
||||
return mediaSourceFactory.createMediaSource(mediaItem)
|
||||
.setMediaSourceFactory(
|
||||
DefaultMediaSourceFactory(context)
|
||||
.setDataSourceFactory(resolvingDataSource)
|
||||
.setLiveTargetOffsetMs(5000)
|
||||
).build()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,6 +106,31 @@ object ExoPlayerHelper {
|
||||
}
|
||||
|
||||
|
||||
private val resolvingDataSource: ResolvingDataSource.Factory by lazy {
|
||||
ResolvingDataSource.Factory(
|
||||
cacheDataSourceFactory
|
||||
) {
|
||||
var res = it
|
||||
|
||||
if (it.uri.toString().contains(SPLIT_TAG)) {
|
||||
val urls = it.uri.toString().split(SPLIT_TAG)
|
||||
val url = urls[0]
|
||||
res = res.withUri(Uri.parse(url))
|
||||
try {
|
||||
val headers: Map<String, String> = gson.fromJson(urls[1], mapType)
|
||||
res = res.withAdditionalHeaders(headers)
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
res
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 支持缓存的DataSource.Factory
|
||||
*/
|
||||
|
@ -7,7 +7,6 @@ import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.graphics.BitmapFactory
|
||||
import android.media.AudioManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.PowerManager
|
||||
import android.support.v4.media.MediaMetadataCompat
|
||||
@ -15,10 +14,10 @@ import android.support.v4.media.session.MediaSessionCompat
|
||||
import android.support.v4.media.session.PlaybackStateCompat
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.media.AudioFocusRequestCompat
|
||||
import com.google.android.exoplayer2.DefaultLoadControl
|
||||
import com.google.android.exoplayer2.ExoPlayer
|
||||
import com.google.android.exoplayer2.PlaybackException
|
||||
import com.google.android.exoplayer2.Player
|
||||
import androidx.media3.common.PlaybackException
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
import io.legado.app.R
|
||||
import io.legado.app.base.BaseService
|
||||
import io.legado.app.constant.*
|
||||
@ -40,6 +39,7 @@ import kotlinx.coroutines.Dispatchers.Main
|
||||
import splitties.systemservices.audioManager
|
||||
import splitties.systemservices.powerManager
|
||||
|
||||
@UnstableApi
|
||||
/**
|
||||
* 音频播放服务
|
||||
*/
|
||||
@ -74,14 +74,7 @@ class AudioPlayService : BaseService(),
|
||||
MediaHelp.buildAudioFocusRequestCompat(this)
|
||||
}
|
||||
private val exoPlayer: ExoPlayer by lazy {
|
||||
ExoPlayer.Builder(this).setLoadControl(
|
||||
DefaultLoadControl.Builder().setBufferDurationsMs(
|
||||
DefaultLoadControl.DEFAULT_MIN_BUFFER_MS,
|
||||
DefaultLoadControl.DEFAULT_MAX_BUFFER_MS,
|
||||
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS / 10,
|
||||
DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS / 10
|
||||
).build()
|
||||
).build()
|
||||
ExoPlayerHelper.createExoPlayer(this)
|
||||
}
|
||||
private var mediaSessionCompat: MediaSessionCompat? = null
|
||||
private var broadcastReceiver: BroadcastReceiver? = null
|
||||
@ -159,13 +152,14 @@ class AudioPlayService : BaseService(),
|
||||
chapter = AudioPlay.durChapter,
|
||||
headerMapF = AudioPlay.headers(true),
|
||||
)
|
||||
val uri = Uri.parse(analyzeUrl.url)
|
||||
//val uri = Uri.parse(analyzeUrl.url)
|
||||
//ExoPlayerHelper.preDownload(uri, analyzeUrl.headerMap)
|
||||
//休息1秒钟,防止403
|
||||
//delay(1000)
|
||||
val mediaSource = ExoPlayerHelper
|
||||
.createMediaSource(uri, analyzeUrl.headerMap)
|
||||
exoPlayer.setMediaSource(mediaSource)
|
||||
// val mediaSource = ExoPlayerHelper
|
||||
// .createMediaSource(uri, analyzeUrl.headerMap)
|
||||
//exoPlayer.setMediaSource(mediaSource)
|
||||
exoPlayer.setMediaItem(ExoPlayerHelper.createMediaItem(analyzeUrl.url,analyzeUrl.headerMap))
|
||||
exoPlayer.playWhenReady = true
|
||||
exoPlayer.prepare()
|
||||
}.onError {
|
||||
@ -234,8 +228,10 @@ class AudioPlayService : BaseService(),
|
||||
/**
|
||||
* 调节速度
|
||||
*/
|
||||
|
||||
private fun upSpeed(adjust: Float) {
|
||||
kotlin.runCatching {
|
||||
@SuppressLint("ObsoleteSdkInt")
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
playSpeed += adjust
|
||||
exoPlayer.setPlaybackSpeed(playSpeed)
|
||||
|
@ -2,10 +2,10 @@ package io.legado.app.service
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.net.Uri
|
||||
import com.google.android.exoplayer2.ExoPlayer
|
||||
import com.google.android.exoplayer2.MediaItem
|
||||
import com.google.android.exoplayer2.PlaybackException
|
||||
import com.google.android.exoplayer2.Player
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.PlaybackException
|
||||
import androidx.media3.common.Player
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
import com.script.ScriptException
|
||||
import io.legado.app.R
|
||||
import io.legado.app.constant.AppLog
|
||||
@ -16,6 +16,7 @@ import io.legado.app.exception.ConcurrentException
|
||||
import io.legado.app.exception.NoStackTraceException
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.help.coroutine.Coroutine
|
||||
import io.legado.app.help.exoplayer.ExoPlayerHelper
|
||||
import io.legado.app.model.ReadAloud
|
||||
import io.legado.app.model.ReadBook
|
||||
import io.legado.app.model.analyzeRule.AnalyzeUrl
|
||||
@ -38,7 +39,8 @@ class HttpReadAloudService : BaseReadAloudService(),
|
||||
Player.Listener {
|
||||
|
||||
private val exoPlayer: ExoPlayer by lazy {
|
||||
ExoPlayer.Builder(this).build()
|
||||
//ExoPlayer.Builder(this).build()
|
||||
ExoPlayerHelper.createExoPlayer(this)
|
||||
}
|
||||
private val ttsFolderPath: String by lazy {
|
||||
cacheDir.absolutePath + File.separator + "httpTTS" + File.separator
|
||||
|
@ -6,7 +6,8 @@ buildscript {
|
||||
build_tool_version = '33.0.1'
|
||||
kotlin_version = '1.8.21'
|
||||
agp_version = '8.0.1'
|
||||
exoplayer_version = '2.18.6'
|
||||
//exoplayer_version = '2.18.6'
|
||||
media3_version = "1.0.1"
|
||||
splitties_version = '3.0.0'
|
||||
room_version = '2.5.1'
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user