diff --git a/README.md b/README.md
index f3f457a..ca1289c 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,11 @@
## 更新日志
+### v1.0.6
+
+* 修复视频可能无声音的问题
+* 修复视频可能无法播放的问题
+
### v1.0.5
* 修复频道配置错误时可能崩溃的问题
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index f6852b6..68115f7 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -64,8 +64,8 @@ fun getVersionName(): String {
}
dependencies {
- implementation("androidx.constraintlayout:constraintlayout:2.1.4")
- val media3Version = "1.3.0-rc01"
+ // 19
+ val media3Version = "1.3.0"
implementation("androidx.media3:media3-ui:$media3Version")
// For media playback using ExoPlayer
@@ -78,8 +78,8 @@ dependencies {
implementation("androidx.leanback:leanback:1.0.0")
implementation("com.github.bumptech.glide:glide:4.11.0")
- // 21:2.9.0 17:2.6.4
- val retrofit2Version = "2.6.4"
+ // 21:2.11.0 17:2.6.4
+ val retrofit2Version = "2.11.0"
implementation("com.squareup.retrofit2:converter-gson:$retrofit2Version")
implementation ("com.squareup.retrofit2:converter-protobuf:$retrofit2Version")
implementation ("com.squareup.retrofit2:retrofit:$retrofit2Version")
@@ -90,6 +90,8 @@ dependencies {
implementation("com.google.android.exoplayer:exoplayer-core:$exoplayerVersion")
implementation("com.google.android.exoplayer:exoplayer-hls:$exoplayerVersion")
- implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0-RC")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
+ implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0-RC")
+
+ implementation(files("libs/lib-decoder-ffmpeg-release.aar"))
}
\ No newline at end of file
diff --git a/app/libs/lib-decoder-ffmpeg-release.aar b/app/libs/lib-decoder-ffmpeg-release.aar
new file mode 100644
index 0000000..fa7bb1d
Binary files /dev/null and b/app/libs/lib-decoder-ffmpeg-release.aar differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 77c9ef8..880e77c 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -46,6 +46,7 @@
android:name="android.hardware.touchscreen"
android:required="false" />
+
diff --git a/app/src/main/java/com/lizongying/mytv0/GroupAdapter.kt b/app/src/main/java/com/lizongying/mytv0/GroupAdapter.kt
index aa7bacf..e429f16 100644
--- a/app/src/main/java/com/lizongying/mytv0/GroupAdapter.kt
+++ b/app/src/main/java/com/lizongying/mytv0/GroupAdapter.kt
@@ -145,7 +145,9 @@ class GroupAdapter(
fun update(tvGroupModel: TVGroupModel) {
this.tvGroupModel = tvGroupModel
- notifyDataSetChanged()
+ recyclerView.post {
+ notifyDataSetChanged()
+ }
}
companion object {
diff --git a/app/src/main/java/com/lizongying/mytv0/ListAdapter.kt b/app/src/main/java/com/lizongying/mytv0/ListAdapter.kt
index e0422cc..d70844e 100644
--- a/app/src/main/java/com/lizongying/mytv0/ListAdapter.kt
+++ b/app/src/main/java/com/lizongying/mytv0/ListAdapter.kt
@@ -1,7 +1,6 @@
package com.lizongying.mytv0
import android.content.Context
-import android.util.Log
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
@@ -111,10 +110,7 @@ class ListAdapter(
viewHolder.bindText(tvModel.tv.title)
- // maybe null
- if (!tvModel.tv.logo.isNullOrBlank()) {
- viewHolder.bindImage(tvModel.tv.logo)
- }
+ viewHolder.bindImage(tvModel.tv.logo)
}
override fun getItemCount() = tvListModel.size()
@@ -125,11 +121,15 @@ class ListAdapter(
binding.textView.text = text
}
- fun bindImage(url: String) {
- Glide.with(context)
- .load(url)
- .centerInside()
- .into(binding.imageView)
+ fun bindImage(url: String?) {
+ if (url.isNullOrBlank()) {
+ binding.imageView.setImageDrawable(null)
+ } else {
+ Glide.with(context)
+ .load(url)
+ .centerInside()
+ .into(binding.imageView)
+ }
}
fun focus(hasFocus: Boolean) {
diff --git a/app/src/main/java/com/lizongying/mytv0/MainActivity.kt b/app/src/main/java/com/lizongying/mytv0/MainActivity.kt
index f2e707e..8884559 100644
--- a/app/src/main/java/com/lizongying/mytv0/MainActivity.kt
+++ b/app/src/main/java/com/lizongying/mytv0/MainActivity.kt
@@ -1,7 +1,9 @@
package com.lizongying.mytv0
+import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
+import android.media.AudioManager
import android.os.Build
import android.os.Bundle
import android.os.Handler
@@ -15,10 +17,12 @@ import android.view.WindowManager
import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import com.lizongying.mytv0.models.TVList
+import kotlin.math.abs
class MainActivity : FragmentActivity() {
+ private var ok = 0
private var playerFragment = PlayerFragment()
private var infoFragment = InfoFragment()
private var channelFragment = ChannelFragment()
@@ -53,8 +57,23 @@ class MainActivity : FragmentActivity() {
.commitNow()
}
- gestureDetector = GestureDetector(this, GestureListener())
+ gestureDetector = GestureDetector(this, GestureListener(this))
+ watch()
+
+ if (!TVList.setPosition(SP.position)) {
+ TVList.setPosition(0)
+ }
+ }
+
+ fun ready() {
+ ok++
+ if (ok == 1) {
+ watch()
+ }
+ }
+
+ fun watch() {
TVList.listModel.forEach { tvModel ->
tvModel.errInfo.observe(this) { _ ->
if (tvModel.errInfo.value != null
@@ -70,6 +89,7 @@ class MainActivity : FragmentActivity() {
if (tvModel.ready.value != null
&& tvModel.tv.id == TVList.position.value
) {
+ playerFragment.play(tvModel)
Log.i(TAG, "info ${tvModel.tv.title}")
infoFragment.show(tvModel)
if (SP.channelNum) {
@@ -78,10 +98,6 @@ class MainActivity : FragmentActivity() {
}
}
}
-
- if (!TVList.setPosition(SP.position)) {
- TVList.setPosition(0)
- }
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
@@ -91,9 +107,13 @@ class MainActivity : FragmentActivity() {
return super.onTouchEvent(event)
}
- private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {
+ private inner class GestureListener(private val context: Context) :
+ GestureDetector.SimpleOnGestureListener() {
+
+ private val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
+ Log.i(TAG, "onSingleTapConfirmed showMenu")
showMenu()
return true
}
@@ -109,18 +129,78 @@ class MainActivity : FragmentActivity() {
velocityX: Float,
velocityY: Float
): Boolean {
- if (velocityY > 0) {
- if (menuFragment.isHidden && settingFragment.isHidden) {
- prev()
+ if ((e1?.x ?: 0f) > windowManager.defaultDisplay.width / 3
+ && (e1?.x ?: 0f) < windowManager.defaultDisplay.width * 2 / 3
+ ) {
+ if (velocityY > 0) {
+ if (menuFragment.isHidden && settingFragment.isHidden) {
+ prev()
+ }
}
- }
- if (velocityY < 0) {
- if (menuFragment.isHidden && settingFragment.isHidden) {
- next()
+ if (velocityY < 0) {
+ if (menuFragment.isHidden && settingFragment.isHidden) {
+ next()
+ }
}
}
+
return super.onFling(e1, e2, velocityX, velocityY)
}
+
+ override fun onScroll(
+ e1: MotionEvent?,
+ e2: MotionEvent,
+ distanceX: Float,
+ distanceY: Float
+ ): Boolean {
+ // 计算手势滑动的方向和距离
+ val deltaY = e1?.y?.let { e2.y.minus(it) } ?: 0f
+ val deltaX = e1?.x?.let { e2.x.minus(it) } ?: 0f
+
+ // 如果是垂直滑动
+ if (abs(deltaY) > abs(deltaX)) {
+ if ((e1?.x ?: 0f) > windowManager.defaultDisplay.width * 2 / 3) {
+ adjustVolume(deltaY) // 调整音量
+ }
+ }
+
+ return super.onScroll(e1, e2, distanceX, distanceY)
+ }
+
+ private fun adjustVolume(deltaY: Float) {
+ val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
+ val currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
+ val deltaVolume = deltaY / 1000 * maxVolume / windowManager.defaultDisplay.height
+
+ var newVolume = currentVolume + deltaVolume
+ if (newVolume < 0) {
+ newVolume = 0F
+ } else if (newVolume > maxVolume) {
+ newVolume = maxVolume.toFloat()
+ }
+
+ audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, newVolume.toInt(), 0)
+
+ // 可以添加一个toast来显示当前音量
+ Toast.makeText(context, "Volume: $newVolume / $maxVolume", Toast.LENGTH_SHORT).show()
+ }
+
+// private fun changeBrightness(deltaBrightness: Float) {
+// brightness += deltaBrightness
+// if (brightness < 0) {
+// brightness = 0f
+// } else if (brightness > 1) {
+// brightness = 1f
+// }
+//
+// val layoutParams = windowManager.attributes
+// layoutParams.screenBrightness = brightness
+// windowManager.attributes = layoutParams
+//
+// // 可以添加一个toast来显示当前亮度
+// Toast.makeText(context, "Brightness: $brightness", Toast.LENGTH_SHORT).show()
+// }
+
}
fun play(position: Int) {
diff --git a/app/src/main/java/com/lizongying/mytv0/MenuFragment.kt b/app/src/main/java/com/lizongying/mytv0/MenuFragment.kt
index 8bb2b25..d458da0 100644
--- a/app/src/main/java/com/lizongying/mytv0/MenuFragment.kt
+++ b/app/src/main/java/com/lizongying/mytv0/MenuFragment.kt
@@ -64,10 +64,15 @@ class MenuFragment : Fragment(), GroupAdapter.ItemListener, ListAdapter.ItemList
listAdapter.setItemListener(this)
TVList.groupModel.tvGroupModel.observe(viewLifecycleOwner) { _ ->
+ (activity as MainActivity).watch()
// not first time
if (TVList.groupModel.tvGroupModel.value != null) {
groupAdapter.update(TVList.groupModel)
+ tvListModel = TVList.groupModel.getTVListModel(TVList.groupModel.position.value!!)
+ if (tvListModel != null) {
+ (binding.list.adapter as ListAdapter).update(tvListModel!!)
+ }
}
}
@@ -90,8 +95,7 @@ class MenuFragment : Fragment(), GroupAdapter.ItemListener, ListAdapter.ItemList
}
}
- override fun onItemClicked(tvModel: TVModel) {
- TVList.setPosition(tvModel.tv.id)
+ override fun onItemClicked(tvModel: TVModel) { TVList.setPosition(tvModel.tv.id)
(activity as MainActivity).hideMenuFragment()
}
diff --git a/app/src/main/java/com/lizongying/mytv0/PlayerFragment.kt b/app/src/main/java/com/lizongying/mytv0/PlayerFragment.kt
index e98d9c8..50eeebe 100644
--- a/app/src/main/java/com/lizongying/mytv0/PlayerFragment.kt
+++ b/app/src/main/java/com/lizongying/mytv0/PlayerFragment.kt
@@ -22,12 +22,10 @@ import androidx.media3.datasource.DefaultHttpDataSource
import androidx.media3.datasource.TransferListener
import androidx.media3.exoplayer.DefaultRenderersFactory
import androidx.media3.exoplayer.ExoPlayer
-import androidx.media3.exoplayer.hls.HlsMediaSource
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector
import androidx.media3.exoplayer.mediacodec.MediaCodecUtil
import com.google.android.exoplayer2.SimpleExoPlayer
import com.lizongying.mytv0.databinding.PlayerBinding
-import com.lizongying.mytv0.models.TVList
import com.lizongying.mytv0.models.TVModel
@@ -65,6 +63,7 @@ class PlayerFragment : Fragment(), SurfaceHolder.Callback {
val renderersFactory = context?.let { DefaultRenderersFactory(it) }
val playerMediaCodecSelector = PlayerMediaCodecSelector()
renderersFactory?.setMediaCodecSelector(playerMediaCodecSelector)
+ renderersFactory?.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON)
player = context?.let {
ExoPlayer.Builder(it)
@@ -93,8 +92,9 @@ class PlayerFragment : Fragment(), SurfaceHolder.Callback {
tvModel?.setReady()
}
})
+
+ (activity as MainActivity).ready()
Log.i(TAG, "player ready")
- ready()
}
})
}
@@ -102,22 +102,6 @@ class PlayerFragment : Fragment(), SurfaceHolder.Callback {
return _binding!!.root
}
- fun ready() {
- TVList.listModel.forEach { tvModel ->
- tvModel.ready.observe(this) { _ ->
-
- // not first time
- if (tvModel.ready.value != null
- && tvModel.tv.id == TVList.position.value
- && tvModel.videoUrl.value != null
-// && tvModel.videoUrl.value != videoUrl
- ) {
- play(tvModel)
- }
- }
- }
- }
-
@OptIn(UnstableApi::class)
fun play(tvModel: TVModel) {
videoUrl = tvModel.videoUrl.value ?: return
@@ -162,13 +146,12 @@ class PlayerFragment : Fragment(), SurfaceHolder.Callback {
}
})
- val hlsMediaSource = HlsMediaSource.Factory(httpDataSource).createMediaSource(
- MediaItem.fromUri(videoUrl)
- )
-
- setMediaSource(hlsMediaSource)
+// val hlsMediaSource = HlsMediaSource.Factory(httpDataSource).createMediaSource(
+// MediaItem.fromUri(videoUrl)
+// )
+// setMediaSource(hlsMediaSource)
-// setMediaItem(MediaItem.fromUri(videoUrl))
+ setMediaItem(MediaItem.fromUri(videoUrl))
prepare()
}
exoPlayer?.run {
@@ -259,8 +242,8 @@ class PlayerFragment : Fragment(), SurfaceHolder.Callback {
}
}
})
+ (activity as MainActivity).ready()
Log.i(TAG, "exoPlayer ready")
- ready()
}
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
diff --git a/app/src/main/java/com/lizongying/mytv0/SettingFragment.kt b/app/src/main/java/com/lizongying/mytv0/SettingFragment.kt
index 77a1295..6222950 100644
--- a/app/src/main/java/com/lizongying/mytv0/SettingFragment.kt
+++ b/app/src/main/java/com/lizongying/mytv0/SettingFragment.kt
@@ -2,17 +2,15 @@ package com.lizongying.mytv0
import android.net.Uri
import android.os.Bundle
-import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.widget.Toast
import androidx.fragment.app.Fragment
import com.lizongying.mytv0.databinding.SettingBinding
import com.lizongying.mytv0.models.TVList
-class SettingFragment: Fragment() {
+class SettingFragment : Fragment() {
private var _binding: SettingBinding? = null
private val binding get() = _binding!!
@@ -52,10 +50,12 @@ class SettingFragment: Fragment() {
}
val updateManager = UpdateManager(context, this, context.appVersionCode)
- binding.checkVersion.setOnClickListener(OnClickListenerCheckVersion(updateManager))
+ binding.checkVersion.setOnClickListener {
+ OnClickListenerCheckVersion(updateManager)
+ (activity as MainActivity).settingActive()
+ }
binding.confirmButton.setOnClickListener {
-
val uriEditText = binding.myEditText
var uri = uriEditText.text.toString()
@@ -65,18 +65,18 @@ class SettingFragment: Fragment() {
} else {
uriEditText.error = "无效的地址"
}
+ (activity as MainActivity).settingActive()
}
binding.appreciate.setOnClickListener {
val imageModalFragment = AppreciateModalFragment()
- // Pass the drawable ID as an argument
val args = Bundle()
args.putInt(AppreciateModalFragment.KEY, R.drawable.appreciate)
imageModalFragment.arguments = args
imageModalFragment.show(requireFragmentManager(), AppreciateModalFragment.TAG)
- Log.i(TAG, "appreciate setOnClickListener")
+ (activity as MainActivity).settingActive()
}
return binding.root
diff --git a/app/src/main/java/com/lizongying/mytv0/models/TVList.kt b/app/src/main/java/com/lizongying/mytv0/models/TVList.kt
index 80d72bc..1887337 100644
--- a/app/src/main/java/com/lizongying/mytv0/models/TVList.kt
+++ b/app/src/main/java/com/lizongying/mytv0/models/TVList.kt
@@ -40,8 +40,6 @@ object TVList {
context.resources.openRawResource(R.raw.channels).bufferedReader()
.use { it.readText() }
}
- Log.i("", "channel $str")
-
groupModel.addTVListModel(TVListModel("我的收藏"))
groupModel.addTVListModel(TVListModel("全部频道"))
@@ -107,6 +105,7 @@ object TVList {
listModel = list.map { tv ->
TVModel(tv)
}
+ setPosition(0)
groupModel.clear()
diff --git a/app/src/main/res/layout/setting.xml b/app/src/main/res/layout/setting.xml
index 2e29807..5eddd40 100644
--- a/app/src/main/res/layout/setting.xml
+++ b/app/src/main/res/layout/setting.xml
@@ -65,11 +65,12 @@
+ android:scrollbars="vertical"
+ android:inputType="textMultiLine" />