Commit 7d910fb1 authored by p x's avatar p x
Browse files

测试直播

parent 10e356d7
...@@ -69,6 +69,12 @@ dependencies { ...@@ -69,6 +69,12 @@ dependencies {
// implementation("com.google.protobuf:protoc:3.0.0") // implementation("com.google.protobuf:protoc:3.0.0")
// implementation("com.google.protobuf:protobuf-kotlin-lite:4.31.1") // implementation("com.google.protobuf:protobuf-kotlin-lite:4.31.1")
//播放器
implementation("androidx.media3:media3-exoplayer:1.8.0")
implementation("androidx.media3:media3-exoplayer-dash:1.8.0")
implementation("androidx.media3:media3-ui:1.8.0")
implementation("androidx.media3:media3-ui-compose:1.8.0")
//java web socket //java web socket
implementation("org.java-websocket:Java-WebSocket:1.6.0") implementation("org.java-websocket:Java-WebSocket:1.6.0")
//proto //proto
......
...@@ -5,10 +5,14 @@ import android.os.Bundle ...@@ -5,10 +5,14 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.annotation.OptIn
import androidx.databinding.DataBindingUtil import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
import androidx.media3.exoplayer.source.MediaSource
import com.sd.cavphmi.net.NetLoadStatus import com.sd.cavphmi.net.NetLoadStatus
import com.sd.cavphmi.utils.ToastHelper import com.sd.cavphmi.utils.ToastHelper
...@@ -175,4 +179,9 @@ open abstract class BaseFragment<Bind : ViewDataBinding, VM : MyBaseViewModel> : ...@@ -175,4 +179,9 @@ open abstract class BaseFragment<Bind : ViewDataBinding, VM : MyBaseViewModel> :
myDialog?.dismiss() myDialog?.dismiss()
} }
@OptIn(UnstableApi::class)
fun createMediaSourceFactory(): MediaSource.Factory{
return DefaultMediaSourceFactory(requireContext()).setLiveTargetOffsetMs(5000L)
}
} }
\ No newline at end of file
...@@ -9,7 +9,7 @@ import com.sd.cavphmi.base.BaseActivity ...@@ -9,7 +9,7 @@ import com.sd.cavphmi.base.BaseActivity
import com.sd.cavphmi.databinding.ActivityMainBinding import com.sd.cavphmi.databinding.ActivityMainBinding
import com.sd.cavphmi.intfaces.OnConCan import com.sd.cavphmi.intfaces.OnConCan
import com.sd.cavphmi.ui.fragment.CarPanelFragment import com.sd.cavphmi.ui.fragment.CarPanelFragment
import com.sd.cavphmi.viewmodels.AvpMapVM import com.sd.cavphmi.ui.fragment.ExoPlayFragment
import com.sd.cavphmi.viewmodels.MainVm import com.sd.cavphmi.viewmodels.MainVm
import com.sd.cavphmi.viewmodels.MockVM import com.sd.cavphmi.viewmodels.MockVM
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
...@@ -41,6 +41,8 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainVm>() { ...@@ -41,6 +41,8 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainVm>() {
//汽车仪表 //汽车仪表
private val carPanelFragment by lazy { CarPanelFragment.newInstance() } private val carPanelFragment by lazy { CarPanelFragment.newInstance() }
//exo播放器
private val exoPlayFragment by lazy { ExoPlayFragment.newInstance("") }
override fun initView() { override fun initView() {
viewModel.mockVM = mockVM viewModel.mockVM = mockVM
...@@ -48,6 +50,10 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainVm>() { ...@@ -48,6 +50,10 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainVm>() {
ft.add(R.id.map_car_pan, carPanelFragment, "1") ft.add(R.id.map_car_pan, carPanelFragment, "1")
ft.commit() ft.commit()
//添加视频播放器,以后看需要控制显示隐藏时机
var ft2= supportFragmentManager.beginTransaction()
ft2.add(R.id.video_frag, exoPlayFragment, "player")
ft2.commit()
} }
override fun getToData() { override fun getToData() {
......
package com.sd.cavphmi.ui.fragment
import android.os.Bundle
import androidx.annotation.OptIn
import androidx.lifecycle.ViewModelProvider
import androidx.media3.common.AudioAttributes
import androidx.media3.common.MediaItem
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
import com.sd.cavphmi.BR
import com.sd.cavphmi.R
import com.sd.cavphmi.base.BaseFragment
import com.sd.cavphmi.base.MyBaseViewModel
import com.sd.cavphmi.databinding.FragmentExoPlayBinding
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val VIDEO_PARAM1 = "video"
private const val ARG_PARAM2 = "param2"
/**
*车内视频播放器
*/
class ExoPlayFragment : BaseFragment<FragmentExoPlayBinding, MyBaseViewModel>() {
private var videoUrl: String = ""
// private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
videoUrl = it.getString(VIDEO_PARAM1, "")
// param2 = it.getString(ARG_PARAM2)
}
}
override fun getStatuBarColor(): Int {
return -1
}
override fun isAutoStatusBarDarkModeEnable(): Boolean {
return false
}
override fun initContentView(): Int {
return R.layout.fragment_exo_play
}
override fun initViewModel(): MyBaseViewModel {
return ViewModelProvider(this).get(MyBaseViewModel::class.java)
}
override fun initVariableId(): Int {
return BR.vm
}
override fun onResume() {
super.onResume()
binding.playerView.onResume()
}
override fun onPause() {
super.onPause()
binding.playerView.onPause()
}
override fun onStop() {
super.onStop()
binding.playerView.onPause()
releasePlayer()
}
override fun onDestroy() {
super.onDestroy()
binding.playerView.getAdViewGroup().removeAllViews()
}
private lateinit var player: ExoPlayer
//用于测试,实际可以传参进来
var videoUri = "https://faw.cuscavp.cn:8443/hdl/live/3.flv"
override fun initView() {
initializePlayer()
}
fun initializePlayer() {
val playerBuilder =
ExoPlayer.Builder(requireContext())
.setMediaSourceFactory(createMediaSourceFactory())
player = playerBuilder.build()
player.addListener(playerEventListener)
player.setAudioAttributes(AudioAttributes.DEFAULT, /* handleAudioFocus= */ true);
player.setPlayWhenReady(true)
binding.playerView.setPlayer(player)
// Build the media item.
val mediaItem = MediaItem.Builder()
.setUri(videoUri)
.setLiveConfiguration(
MediaItem.LiveConfiguration.Builder()
.setMaxPlaybackSpeed(1.02f)
.setMinPlaybackSpeed(0.9f)
.build()
)
.build()
player.setMediaItem(mediaItem)
player.prepare()
// Start the playback.
// player.play()
}
fun releasePlayer() {
player.release()
binding.playerView.setPlayer(/* player= */ null);
}
private var playerEventListener=object : Player.Listener{
override fun onPlayerError(error: PlaybackException) {
super.onPlayerError(error)
}
}
companion object {
@JvmStatic
fun newInstance(video: String) =
ExoPlayFragment().apply {
arguments = Bundle().apply {
putString(VIDEO_PARAM1, video)
}
}
// @JvmStatic
// fun newInstance(param1: String, param2: String) =
// ExoPlayFragment().apply {
// arguments = Bundle().apply {
// putString(ARG_PARAM1, param1)
// putString(ARG_PARAM2, param2)
// }
// }
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="10dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" <layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<data> <data>
...@@ -14,6 +13,7 @@ ...@@ -14,6 +13,7 @@
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context=".ui.MainActivity"> tools:context=".ui.MainActivity">
...@@ -61,11 +61,11 @@ ...@@ -61,11 +61,11 @@
android:text="V2X预警开始" /> android:text="V2X预警开始" />
<!-- <Button--> <!-- <Button-->
<!-- android:id="@+id/bt_status"--> <!-- android:id="@+id/bt_status"-->
<!-- android:layout_width="wrap_content"--> <!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"--> <!-- android:layout_height="wrap_content"-->
<!-- android:text="网联车辆状态" />--> <!-- android:text="网联车辆状态" />-->
<!-- <Button--> <!-- <Button-->
<!-- android:id="@+id/bt_tarpre"--> <!-- android:id="@+id/bt_tarpre"-->
<!-- android:layout_width="wrap_content"--> <!-- android:layout_width="wrap_content"-->
...@@ -83,6 +83,15 @@ ...@@ -83,6 +83,15 @@
</LinearLayout> </LinearLayout>
<FrameLayout
android:id="@+id/video_frag"
android:layout_width="500dp"
android:layout_height="360dp"
android:layout_alignParentBottom="true"
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
android:background="@drawable/rect_no_col_10" />
<!-- <include--> <!-- <include-->
<!-- layout="@layout/order_detail"--> <!-- layout="@layout/order_detail"-->
<!-- android:layout_width="wrap_content"--> <!-- android:layout_width="wrap_content"-->
......
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- <FrameLayout xmlns:tools="http://schemas.android.com/tools"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="match_parent"-->
<!-- -->
<!-- tools:context=".ui.fragment.ExoPlayFragment">-->
<!-- app:show_shuffle_button="true"-->
<!-- app:show_subtitle_button="true"-->
<androidx.media3.ui.PlayerView
android:id="@+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:resize_mode="fill" />
<!-- </FrameLayout>-->
</layout>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment