feat:优化视频播放功能,包括下载、播放、暂停和停止视频。
This commit is contained in:
parent
db59e63779
commit
be40211f41
13
.idea/deploymentTargetDropDown.xml
generated
13
.idea/deploymentTargetDropDown.xml
generated
@ -4,6 +4,17 @@
|
||||
<value>
|
||||
<entry key="app">
|
||||
<State>
|
||||
<runningDeviceTargetSelectedWithDropDown>
|
||||
<Target>
|
||||
<type value="RUNNING_DEVICE_TARGET" />
|
||||
<deviceKey>
|
||||
<Key>
|
||||
<type value="VIRTUAL_DEVICE_PATH" />
|
||||
<value value="D:\Android\.android\avd\Pixel_7_API_34.avd" />
|
||||
</Key>
|
||||
</deviceKey>
|
||||
</Target>
|
||||
</runningDeviceTargetSelectedWithDropDown>
|
||||
<targetSelectedWithDropDown>
|
||||
<Target>
|
||||
<type value="QUICK_BOOT_TARGET" />
|
||||
@ -15,7 +26,7 @@
|
||||
</deviceKey>
|
||||
</Target>
|
||||
</targetSelectedWithDropDown>
|
||||
<timeTargetWasSelectedWithDropDown value="2024-04-24T08:47:36.516818Z" />
|
||||
<timeTargetWasSelectedWithDropDown value="2024-04-25T02:40:10.447031700Z" />
|
||||
</State>
|
||||
</entry>
|
||||
</value>
|
||||
|
||||
@ -1,9 +1,15 @@
|
||||
package com.timber.soft.mylivewallpaper.tools
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.View
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.GlideException
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.google.gson.Gson
|
||||
import com.jakewharton.rxbinding4.view.clicks
|
||||
import com.timber.soft.mylivewallpaper.data.WallpaperData
|
||||
@ -14,13 +20,11 @@ import java.util.concurrent.TimeUnit
|
||||
|
||||
object AppTools {
|
||||
|
||||
private const val DIR_FILE_NAME = "tep"
|
||||
private const val DIR_DOWNLOAD = "download"
|
||||
|
||||
fun View.throttleClicks(time: Long = 1000, block: (View) -> Unit) {
|
||||
this.clicks().throttleFirst(time, TimeUnit.MILLISECONDS).subscribe { block(this) }
|
||||
}
|
||||
|
||||
|
||||
fun onMain(operation: () -> Unit) = Handler(Looper.getMainLooper()).post(operation)
|
||||
fun parseJsonFile(jsonInputStream: InputStream): List<WallpaperData> {
|
||||
val reader = InputStreamReader(jsonInputStream)
|
||||
@ -28,39 +32,28 @@ object AppTools {
|
||||
return Gson().fromJson(jsonString, Array<WallpaperData>::class.java).toMutableList()
|
||||
}
|
||||
|
||||
private fun getDownloadDirectory(): String {
|
||||
return getDefaultDirectory() + File.separator + DIR_DOWNLOAD
|
||||
}
|
||||
|
||||
private fun getDefaultDirectory(): String {
|
||||
var dirName = ""
|
||||
if (MyApplication.appContext.getExternalFilesDir(DIR_FILE_NAME) != null) {//外部存储可用
|
||||
if (Build.VERSION.SDK_INT >= 29) {
|
||||
dirName = MyApplication.appContext.getExternalFilesDir(DIR_FILE_NAME)!!.path
|
||||
} else if (Build.VERSION.SDK_INT < 29) {
|
||||
dirName = MyApplication.appContext.getExternalFilesDir(DIR_FILE_NAME)!!.absolutePath
|
||||
fun glideDownload(context: Context, url: String, downloadCall: (File?) -> Unit) {
|
||||
Glide.with(context).downloadOnly().load(url).addListener(object : RequestListener<File> {
|
||||
override fun onLoadFailed(
|
||||
e: GlideException?,
|
||||
model: Any?,
|
||||
target: Target<File>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
downloadCall.invoke(null)
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
dirName = MyApplication.appContext.filesDir.absolutePath
|
||||
}
|
||||
return dirName
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: File?,
|
||||
model: Any?,
|
||||
target: Target<File>?,
|
||||
dataSource: DataSource?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
downloadCall.invoke(resource)
|
||||
return false
|
||||
}
|
||||
}).preload()
|
||||
}
|
||||
|
||||
fun getFileName(url: String): String {
|
||||
return url.substring(url.lastIndexOf("/") + 1)
|
||||
}
|
||||
|
||||
fun getFilePath(url: String): String {
|
||||
return getDownloadDirectory() + File.separator + getFileName(url)
|
||||
}
|
||||
|
||||
fun getFile(url: String): File {
|
||||
return File(getFilePath(url))
|
||||
}
|
||||
|
||||
fun isExist(url: String): Boolean {
|
||||
return File(getFilePath(url)).exists()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -2,10 +2,13 @@ package com.timber.soft.mylivewallpaper.ui.activity
|
||||
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.media.MediaPlayer
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.view.SurfaceHolder
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.isVisible
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
@ -13,11 +16,12 @@ import com.bumptech.glide.load.engine.GlideException
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.timber.soft.mylivewallpaper.R
|
||||
import com.timber.soft.mylivewallpaper.data.AppDatabase
|
||||
import com.timber.soft.mylivewallpaper.data.WallpaperData
|
||||
import com.timber.soft.mylivewallpaper.databinding.ActivityDetailsBinding
|
||||
import com.timber.soft.mylivewallpaper.tools.AppFinalString
|
||||
import com.timber.soft.mylivewallpaper.tools.AppTools.isExist
|
||||
import com.timber.soft.mylivewallpaper.tools.AppTools.glideDownload
|
||||
import com.timber.soft.mylivewallpaper.ui.customerView.DownLoadDialog
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -28,6 +32,9 @@ class DetailActivity : BaseActivity(), View.OnClickListener {
|
||||
private lateinit var binding: ActivityDetailsBinding
|
||||
private lateinit var wallpaperData: WallpaperData
|
||||
private lateinit var downDialog: DownLoadDialog
|
||||
private var mediaPlayer: MediaPlayer? = null
|
||||
private lateinit var videoUrl: String
|
||||
private var isDownload = false
|
||||
override fun getActivityContentView(): View {
|
||||
binding = ActivityDetailsBinding.inflate(layoutInflater)
|
||||
return binding.root
|
||||
@ -85,6 +92,7 @@ class DetailActivity : BaseActivity(), View.OnClickListener {
|
||||
binding.detailsCollect.setOnClickListener(this)
|
||||
binding.detailsSet.setOnClickListener(this)
|
||||
binding.detailsPlayButton.setOnClickListener(this)
|
||||
binding.detailsVideoBack.setOnClickListener(this)
|
||||
binding.detailsCollect.isSelected = wallpaperData.isCollect
|
||||
}
|
||||
|
||||
@ -103,15 +111,32 @@ class DetailActivity : BaseActivity(), View.OnClickListener {
|
||||
}
|
||||
|
||||
binding.detailsPlayButton -> {
|
||||
if (isExist()) {
|
||||
if (isDownload) {
|
||||
binding.detailsPlayButton.isVisible = false
|
||||
playVideo()
|
||||
} else {
|
||||
binding.detailsPlayButton.isVisible = false
|
||||
binding.detailsProgressbar.isVisible = true
|
||||
showDownloadDialog()
|
||||
}
|
||||
}
|
||||
|
||||
binding.detailsVideoBack -> {
|
||||
stopVideo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopVideo() {
|
||||
try {
|
||||
mediaPlayer?.stop()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
binding.detailsFlPlay.isVisible = false
|
||||
binding.detailsPlayButton.isVisible = true
|
||||
}
|
||||
|
||||
private fun setCollect() {
|
||||
if (!binding.detailsCollect.isSelected) {
|
||||
binding.detailsCollect.isSelected = !binding.detailsCollect.isSelected
|
||||
@ -138,15 +163,119 @@ class DetailActivity : BaseActivity(), View.OnClickListener {
|
||||
}
|
||||
|
||||
private fun showDownloadDialog() {
|
||||
Log.e("file_play", "file is null!")
|
||||
wallpaperData.preview.let {
|
||||
glideDownload(this, it) { file ->
|
||||
if (file == null) {
|
||||
isDownload = false
|
||||
Toast.makeText(
|
||||
this@DetailActivity, "Sorry, the download failed.", Toast.LENGTH_SHORT
|
||||
).show()
|
||||
binding.detailsProgressbar.isVisible = false
|
||||
} else {
|
||||
binding.detailsProgressbar.isVisible = false
|
||||
file.absolutePath.let { path ->
|
||||
// mediaPlayer.setDataSource(path)
|
||||
// mediaPlayer.prepare()
|
||||
videoUrl = path
|
||||
isDownload = true
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
AppDatabase.dataBase.getWallpaperDao().insertData(wallpaperData.apply {
|
||||
downloadUrl = path
|
||||
})
|
||||
}
|
||||
playVideo()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun playVideo() {
|
||||
Log.e("file_play", "file is exist!")
|
||||
try {
|
||||
if (mediaPlayer == null) {
|
||||
mediaPlayer = MediaPlayer()
|
||||
binding.detailsSurfaceVideo.holder.addCallback(object : SurfaceHolder.Callback {
|
||||
override fun surfaceCreated(holder: SurfaceHolder) {
|
||||
try {
|
||||
mediaPlayer?.reset()
|
||||
mediaPlayer?.setDataSource(videoUrl)
|
||||
mediaPlayer?.setDisplay(holder)
|
||||
mediaPlayer?.isLooping = true
|
||||
mediaPlayer?.setVolume(0f, 0f)
|
||||
mediaPlayer?.setOnPreparedListener {
|
||||
try {
|
||||
it.start()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
mediaPlayer?.prepareAsync()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun surfaceChanged(
|
||||
holder: SurfaceHolder,
|
||||
format: Int,
|
||||
width: Int,
|
||||
height: Int
|
||||
) {
|
||||
}
|
||||
|
||||
override fun surfaceDestroyed(holder: SurfaceHolder) {
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
mediaPlayer?.reset()
|
||||
mediaPlayer?.setDataSource(videoUrl)
|
||||
mediaPlayer?.isLooping = true
|
||||
mediaPlayer?.setVolume(0f, 0f)
|
||||
mediaPlayer?.prepare()
|
||||
}
|
||||
binding.detailsFlPlay.isVisible = true
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun isExist(): Boolean {
|
||||
return isExist(wallpaperData.preview)
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mediaPlayer?.stop()
|
||||
mediaPlayer?.release()
|
||||
mediaPlayer = null
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
super.onBackPressed()
|
||||
if (binding.detailsFlPlay.isVisible) {
|
||||
stopVideo()
|
||||
return
|
||||
}
|
||||
finish()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (binding.detailsFlPlay.isVisible) {
|
||||
try {
|
||||
stopVideo()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (binding.detailsFlPlay.isVisible) {
|
||||
try {
|
||||
mediaPlayer?.start()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -10,23 +10,11 @@ import com.timber.soft.mylivewallpaper.databinding.ViewDownloaddialogBinding
|
||||
import com.timber.soft.mylivewallpaper.tools.AppTools.throttleClicks
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
/**
|
||||
* TODO : no implement
|
||||
*/
|
||||
class DownLoadDialog(
|
||||
private val context: Context,
|
||||
private val url: String,
|
||||
private val title: String = "",
|
||||
init: DownLoadDialog.() -> Unit
|
||||
) : Dialog(context, R.style.DownLoadDialog) {
|
||||
private lateinit var binding: ViewDownloaddialogBinding
|
||||
var onDownloadSuccess: (() -> Unit)? = null
|
||||
var onDownloadFailed: (() -> Unit)? = null
|
||||
private var mCount: AtomicInteger = AtomicInteger(0)
|
||||
|
||||
init {
|
||||
init()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@ -43,13 +31,10 @@ class DownLoadDialog(
|
||||
}
|
||||
|
||||
private fun startDownload() {
|
||||
binding.dialogProgressbar.progress = 0f
|
||||
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
if (!TextUtils.isEmpty(title)) {
|
||||
binding.dialogText.text = title
|
||||
}
|
||||
binding.dialogIvClose.throttleClicks {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
@ -94,14 +94,15 @@
|
||||
android:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/details_ivClose"
|
||||
android:id="@+id/details_video_back"
|
||||
android:layout_width="54dp"
|
||||
android:layout_height="54dp"
|
||||
android:layout_gravity="end"
|
||||
android:layout_gravity="start"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginTop="46dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:src="@drawable/svg_back"
|
||||
android:visibility="visible" />
|
||||
android:background="@drawable/shape_circular"
|
||||
android:padding="12dp"
|
||||
android:src="@drawable/svg_back" />
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user