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

测试直播

parent 10e356d7
......@@ -69,6 +69,12 @@ dependencies {
// implementation("com.google.protobuf:protoc:3.0.0")
// 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
implementation("org.java-websocket:Java-WebSocket:1.6.0")
//proto
......
......@@ -5,10 +5,14 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.OptIn
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
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.utils.ToastHelper
......@@ -175,4 +179,9 @@ open abstract class BaseFragment<Bind : ViewDataBinding, VM : MyBaseViewModel> :
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
import com.sd.cavphmi.databinding.ActivityMainBinding
import com.sd.cavphmi.intfaces.OnConCan
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.MockVM
import dagger.hilt.android.AndroidEntryPoint
......@@ -41,6 +41,8 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainVm>() {
//汽车仪表
private val carPanelFragment by lazy { CarPanelFragment.newInstance() }
//exo播放器
private val exoPlayFragment by lazy { ExoPlayFragment.newInstance("") }
override fun initView() {
viewModel.mockVM = mockVM
......@@ -48,6 +50,10 @@ class MainActivity : BaseActivity<ActivityMainBinding, MainVm>() {
ft.add(R.id.map_car_pan, carPanelFragment, "1")
ft.commit()
//添加视频播放器,以后看需要控制显示隐藏时机
var ft2= supportFragmentManager.beginTransaction()
ft2.add(R.id.video_frag, exoPlayFragment, "player")
ft2.commit()
}
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"?>
<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">
<data>
......@@ -14,6 +13,7 @@
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context=".ui.MainActivity">
......@@ -61,11 +61,11 @@
android:text="V2X预警开始" />
<!-- <Button-->
<!-- android:id="@+id/bt_status"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="网联车辆状态" />-->
<!-- <Button-->
<!-- android:id="@+id/bt_status"-->
<!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="网联车辆状态" />-->
<!-- <Button-->
<!-- android:id="@+id/bt_tarpre"-->
<!-- android:layout_width="wrap_content"-->
......@@ -83,6 +83,15 @@
</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-->
<!-- layout="@layout/order_detail"-->
<!-- 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