当前位置: 首页 > news >正文

响应式网站建设特色重庆建设部网站

响应式网站建设特色,重庆建设部网站,网站优化外包费用,工业设计公司官网前言:本文只是练习,本文只是练习,本文只是练习! 直播的核心就是推流和拉流,我们就以RTMP的协议来实现下推流和拉流,其他的协议等我学习后再来补充 1.推流 1.1搭建流媒体服务器,具体搭建方法请参…

前言:本文只是练习,本文只是练习,本文只是练习!
直播的核心就是推流和拉流,我们就以RTMP的协议来实现下推流和拉流,其他的协议等我学习后再来补充
1.推流
1.1搭建流媒体服务器,具体搭建方法请参照Windows搭建RTMP服务器_rtmp服务器搭建-CSDN博客
一些软件需要搭梯子,如果没法下载的,可以联系下我,我私发,搭建好后,在浏览器里输入http://localhost:9091/stat 



出现该界面,说明搭建成功
1.2推流,上面的搭建文章,有OBS推流和ffmpeg推流,这些推流是软件操作和命令行操作,在Andorid客户端不方便,我们这里采用WangShuo1143368701/WSLiveDemo: 音视频,直播SDK,rtmp推流,录制视频,滤镜。百万用户,线上迭代半年,已经稳定。这个库来进行推流
1.2.1首先build.gradle里进行依赖

implementation 'com.github.WangShuo1143368701:WSLiveDemo:v1.7'

1.2.2进行ndk配置

defaultConfig {applicationId "com.anssy.videolive"minSdk 24targetSdk 34versionCode 1versionName "1.0"ndk {// 设置支持的SO库架构(开发者可以根据需要,选择一个或多个平台的so)abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "arm64-v8a", "x86_64"}testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}

1.2.3 接下来,就是一些权限的申请,布局的编写,和对应代码的实现了,申请的权限是Camera和Record Audio
这里引入一个常用的权限框架

 implementation 'com.github.getActivity:XXPermissions:20.0'

具体实现代码:

activity_live_video.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><me.lake.librestreaming.ws.StreamLiveCameraViewandroid:id="@+id/stream_previewView"android:layout_width="match_parent"android:layout_above="@id/bottom_layout"android:layout_height="match_parent"/><LinearLayoutandroid:layout_width="match_parent"android:orientation="horizontal"android:id="@+id/bottom_layout"android:layout_alignParentBottom="true"android:layout_height="wrap_content"><Buttonandroid:layout_width="0dp"android:text="开始推流"android:id="@+id/btn_startStreaming"android:layout_height="wrap_content"android:layout_weight="1"/><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="停止推流"android:id="@+id/btn_stopStreaming"/><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:id="@+id/watch_live"android:text="查看直播"/><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:id="@+id/btn_startRecord"android:text="开始录制"/><Buttonandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:id="@+id/btn_stopRecord"android:text="停止录制"/></LinearLayout>
</RelativeLayout>

MainActivity.kt  这里有个注意点,就是这个rtmp的地址,自己搞了半天,这个地址是你本地的IP+在niginx里config文件里面配置的端口号,然后后面的程序名称默认是live,也可以是你配置的程序,具体看画红框的部分


 

package com.anssy.videolive.uiimport android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.View.OnClickListener
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.anssy.videolive.R
import com.anssy.videolive.databinding.ActivityLiveVideoBinding
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import jp.co.cyberagent.android.gpuimage.GPUImageAddBlendFilter
import me.lake.librestreaming.core.listener.RESConnectionListener
import me.lake.librestreaming.filter.hardvideofilter.BaseHardVideoFilter
import me.lake.librestreaming.filter.hardvideofilter.HardVideoGroupFilter
import me.lake.librestreaming.ws.StreamAVOption
import me.lake.librestreaming.ws.StreamLiveCameraView
import me.lake.librestreaming.ws.filter.hardfilter.GPUImageBeautyFilter
import me.lake.librestreaming.ws.filter.hardfilter.extra.GPUImageCompatibleFilter
import java.util.LinkedList/*** @Description rtmp的直播练习* @Author yulu* @CreateTime 2025年01月21日 09:14:03*/class MainActivity :AppCompatActivity(),RESConnectionListener,OnClickListener{private lateinit var mLiveCameraView: StreamLiveCameraViewprivate lateinit var streamAVOption: StreamAVOptionprivate val rtmpUrl = "rtmp://192.168.0.209:1935/hls/"private lateinit var mMainViewBinding:ActivityLiveVideoBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)mMainViewBinding = ActivityLiveVideoBinding.inflate(layoutInflater)setContentView(mMainViewBinding.root)initView()requestPermission()}/*** 请求权限*/private fun requestPermission() {val permissionList: MutableList<String> = ArrayList()permissionList.add(Permission.CAMERA)permissionList.add(Permission.RECORD_AUDIO)XXPermissions.with(this).permission(permissionList).request(object : OnPermissionCallback {override fun onGranted(permissions: List<String>, all: Boolean) {if (all) {initConfig()}}override fun onDenied(permissions: List<String>, never: Boolean) {}})}private fun initView(){mLiveCameraView = mMainViewBinding.streamPreviewViewmMainViewBinding.btnStartStreaming.setOnClickListener(this)mMainViewBinding.btnStopStreaming.setOnClickListener(this)mMainViewBinding.btnStartRecord.setOnClickListener(this)mMainViewBinding.btnStopRecord.setOnClickListener(this)mMainViewBinding.watchLive.setOnClickListener(this)}/*** 进行相关配置*/private fun initConfig() {//参数配置 startstreamAVOption = StreamAVOption()streamAVOption.streamUrl = rtmpUrl//参数配置 endmLiveCameraView.init(this, streamAVOption)mLiveCameraView.addStreamStateListener(this)//设置滤镜组val files = LinkedList<BaseHardVideoFilter>()files.add(GPUImageCompatibleFilter(GPUImageBeautyFilter()))files.add(GPUImageCompatibleFilter(GPUImageAddBlendFilter()))mLiveCameraView.setHardVideoFilter(HardVideoGroupFilter(files))}override fun onDestroy() {super.onDestroy()mLiveCameraView.destroy()}override fun onOpenConnectionResult(result: Int) {//result 0成功  1 失败runOnUiThread {Toast.makeText(this,"打开推流连接 状态:$result 推流地址:$rtmpUrl", Toast.LENGTH_LONG).show()}}override fun onWriteError(result: Int) {runOnUiThread {Toast.makeText(this,"推流出错,请尝试重连",Toast.LENGTH_LONG).show()}}override fun onCloseConnectionResult(result: Int) {runOnUiThread {Toast.makeText(this,"关闭推流连接 状态:$result",Toast.LENGTH_LONG).show()}}override fun onClick(v: View) {when(v.id){//开始推流R.id.btn_startStreaming-> {if (!mLiveCameraView.isStreaming) {mLiveCameraView.startStreaming(rtmpUrl)} else {Toast.makeText(this, "未打开", Toast.LENGTH_SHORT).show()}}//结束推流R.id.btn_stopStreaming->{if (mLiveCameraView.isStreaming) {mLiveCameraView.stopStreaming()}}//查看直播R.id.watch_live->{val intent = Intent(this,VideoLiveActivity::class.java)intent.putExtra("url",this.rtmpUrl)startActivity(intent)}//开始录制R.id.btn_startRecord->{if (!mLiveCameraView.isRecord) {mLiveCameraView.startRecord()}}//结束录制R.id.btn_stopRecord->{if (mLiveCameraView.isRecord) {mLiveCameraView.stopRecord()}}}}}

      弄完后,就可以推流了,推流成功的效果如下

2.拉流
2.1 VLC播放器播放,在VLC播放器中输入推流的地址
点击媒体->打开网络串流->输入地址

rtmp://192.168.0.209:1935/hls/

2.2使用IJK内核的播放器来播放该地址,这里引入一个第三方库
Doikki/DKVideoPlayer: Android Video Player. 安卓视频播放器,封装MediaPlayer、ExoPlayer、IjkPlayer。模仿抖音并实现预加载,列表播放,悬浮播放,广告播放,弹幕,视频水印,视频滤镜
build.gradle中依赖

    implementation 'xyz.doikki.android.dkplayer:dkplayer-java:3.3.7'implementation 'xyz.doikki.android.dkplayer:player-ijk:3.3.7'implementation 'xyz.doikki.android.dkplayer:dkplayer-ui:3.3.7'

application中初始化

package com.anssy.videolive.baseimport android.app.Application
import xyz.doikki.videoplayer.ijk.IjkPlayerFactory
import xyz.doikki.videoplayer.player.VideoViewConfig
import xyz.doikki.videoplayer.player.VideoViewManager/*** @Description TODO* @Author yulu* @CreateTime 2025年01月21日 09:44:15*/class BaseApplication : Application() {override fun onCreate() {super.onCreate()VideoViewManager.setConfig(VideoViewConfig.newBuilder().setPlayerFactory(IjkPlayerFactory.create())//使用使用IjkPlayer解码 直播使用.build())}}

activity_video_play.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:background="@color/black"android:layout_height="match_parent"><xyz.doikki.videoplayer.player.VideoViewandroid:id="@+id/player"android:layout_centerInParent="true"android:layout_width="match_parent"android:layout_height="match_parent" /><LinearLayoutandroid:layout_width="45dp"android:layout_height="45dp"android:onClick="back"android:id="@+id/back_layout"android:orientation="horizontal"tools:ignore="UsingOnClickInXml"><ImageViewandroid:id="@+id/img_back"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:contentDescription="@null"android:scaleType="centerInside"android:src="@drawable/back_sting_white" /></LinearLayout>
</RelativeLayout>

VideoLiveActivity.kt

package com.anssy.videolive.uiimport android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.anssy.videolive.databinding.ActivityVideoPlayBinding
import xyz.doikki.videocontroller.StandardVideoController/*** @Description 用于直播播放的控制器* @Author yulu* @CreateTime 2025年01月21日 09:50:41*/class VideoLiveActivity : AppCompatActivity() {private lateinit var mVideoLiveVideoBinding: ActivityVideoPlayBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)mVideoLiveVideoBinding = ActivityVideoPlayBinding.inflate(layoutInflater)setContentView(mVideoLiveVideoBinding.root)initView()}private fun initView() {mVideoLiveVideoBinding.player.setUrl(if (intent.getStringExtra("url")==null) "rtmp://192.168.0.209:1935/hls/" else intent.getStringExtra("url")) //设置视频地址val controller = StandardVideoController(this)controller.addDefaultControlComponent("", false)mVideoLiveVideoBinding.player.setVideoController(controller) //设置控制器mVideoLiveVideoBinding.player.start() //开始播放,不调用则不自动播放}public fun back(view:View){finish()}override fun onPause() {super.onPause()mVideoLiveVideoBinding.player.pause()}override fun onResume() {super.onResume()mVideoLiveVideoBinding.player.resume()}override fun onDestroy() {super.onDestroy()mVideoLiveVideoBinding.player.release()}override fun onBackPressed() {if (!mVideoLiveVideoBinding.player.onBackPressed()) {super.onBackPressed()}}
}

播放效果:

20250121_112120

源码下载地址:rtmp练习,kotlin资源-CSDN文库

http://www.yayakq.cn/news/885819/

相关文章:

  • html设计主题网站代码WordPress长文章索引插件
  • 怎样用wordpress建站电子商务网站建设与运营
  • 响应式自适应网站模板网站建设中的财务预算
  • 品牌网站建设 杭州网页qq登录空间
  • 网页设计做一个网站wordpress android下载
  • php 网站 模板公司建立网站的步骤
  • 安卓手机软件开发外包网站优化什么意思
  • 企业网站前期建设常见的网站开发工具
  • wordpress 30天热门google seo是什么
  • 自己做的网站安全吗旅游景区网站模板
  • 济宁市兖州区城市建设局网站wordpress 仿站 菜单
  • 成安网站建设做综合类网站好不好
  • 比一网站建设成都网站建设 龙兵
  • 建设银行哈尔滨分行网站网站解析什么意思
  • 网站有标题手机网站百度关键词排名
  • 开发区网站开发语言都有哪些做二手挖机的网站
  • 企业网站备案多少钱网站描述怎么修改吗
  • 凡科轻站小程序怎么样网站毕业设计代做
  • 如何自己做网站发布到服务器上面详细的网站规划建设方案服务器
  • 电商网站建设精英个人业务网站创建
  • 关于网站建设公司大全荆州seo推广
  • 统一企业官方网站亚星管理网代理平台入口
  • 合优做网站需要多少钱wordpress 免费好用主题
  • 建设局网站作用辽宁省工程造价网
  • 买了个网站后怎么做的网站建设费属于广告费
  • 专门发布采购信息的网站做网站的首页下拉列表
  • 公司网站找谁做鞍山做网站团队
  • 重庆网站制作1000wordpress页面加载时间插件
  • 做网站团队微信小程序怎么添加到桌面
  • 网站首页横版图怎么做陕西网站备案