Android Red5视频通讯第四篇:推流

Android Red5视频通讯第四篇:推流

1.布局视频预览

<com.xxx.xxx.WechatCameraView

        android:id="@+id/wechat_cameraview"

        android:layout_width="79px"

        android:layout_height="106px"

        android:layout_alignParentEnd="true"

        android:layout_alignParentBottom="true" />

2.初始化publishClient,camera,audioMicro,publishstream,以及回调接口

var publishClient: INetConnection? = null;
var camera: WechatCamera? = null
var audioMicro: WechatAudioMicro? = null
var publishstream: UltraNetStream? = null
var disConnected=true

 紧接着第一篇的连接成功的接口,赋值publishClient

  /**
     * 连接服务器接口回调
     */
  val connectServerCallback = object : INetConnection.ListenerAdapter() {
   override fun onAsyncError(source:NetConnection?,message:String?,e: Exception?)       {
            Log.i(TAG, "connectServerCallback onAsyncError: $message $e")
}
   override fun onIOError(source: INetConnection?, message: String?)
 {
            Log.i(TAG, "connectServerCallback#onIOError: " + message!!)
}

override fun onNetStatus(source: INetConnection?, info: Map<String, Any>)
 {
            Log.i(TAG, "connectServerCallback #onNetStatus: $info")
            val code = info["code"]
            if (NetConnection.CONNECT_SUCCESS == code) {
                //连接成功,取得publishClient
              publishClient = source
              disConnected=false
            } else {
                disConnected=true
                publishClient = null;
            }
}

}


/**
     * 发布回调接口
     */
val outGoingCallPublishCallback = object : INetStream.ListenerAdapter()
{
        override fun onNetStatus(iNetStream: INetStream?, info: Map<String, Any>) {
            Log.i(TAG, "outGoingCallPublishCallback#onNetStatus: $info")
            val code = info["code"]
            when {
                NetStream.PUBLISH_START == code -> {
                //发布成功
                Log.i(TAG, "outGoingCallPublishCallback PUBLISH_START")
                                  }
                NetStream.RECORD_START == code -> {
                //开始记录
                Log.i(TAG, "outGoingCallPublishCallback RECORD_START")
                }
                NetStream.UNPUBLISH_SUCCESS == code -> {
                Log.i(TAG,"outGoingCallPublishCallbackUNPUBLISH_SUCCESS")
                                   }
                NetStream.PUBLISH_BADNAME == code -> {
                Log.i(TAG, "outGoingCallPublishCallback PUBLISH_BADNAME")
                }
            }         
 }

}



 

3.初始化Micro和Camera

//调用initinitMicroAndCameta 方法初始化麦克风和摄像头
initMicroAndCameta(wechat_cameraview.wechatCamera)
/**
* 初始化摄像头和麦克风
* */
fun initMicroAndCameta(camera: WechatCamera)
{
        this.audioMicro = WechatAudioMicro()
        this.camera = camera
}

 

4.开始推流

/**向服务器推送视频流*/
fun outGoingCallPublish()
{
 singleExecutor.execute(Runnable {
 if (publishClient != null && !disconnected)
{
   startRecord()
   publishstream = UltraNetStream(publishClient)//新建发布流
   publishstream!!.attachAudio(audioMicro)//设置麦克风
   publishstream!!.attachCamera(camera, -1)//设置摄像头
   publishstream!!.addEventListener(outGoingCallPublishCallback)//设置回调接口
}
   publishName = publish(publishstream)
   userProfile!!.publishid = publishName
   })
}

/**
* 开始录制视频和声音
*/
private fun startRecord() {
     if (camera != null)
      camera!!.start()
     if (audioMicro != null)
      audioMicro!!.start()
}

    /**
     * 向服务器推送视频音频流
     */
private fun publish(publishStrem: UltraNetStream?): String {
        if (publishStrem == null) {
            Log.i(TAG, "publishStream not ready")
            return ""
        }
        val calendar = Calendar.getInstance()
        val year = calendar.get(Calendar.YEAR)
        val month = calendar.get(Calendar.MONTH)
        val day = calendar.get(Calendar.DAY_OF_MONTH)
        val hour = calendar.get(Calendar.HOUR_OF_DAY)
        val min = calendar.get(Calendar.MINUTE)
        val second = calendar.get(Calendar.SECOND)
        val publishName = "" + year + (month + 1) + day + hour + min + second
        Log.i(TAG, "publishStream publish:$publishName")
        publishStrem?.publish(publishName, NetStream.RECORD)
        return publishName
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一: 使用javacv来实现,最终也是用过ffmpeg来进行编码和推流,javacv实现到可以直接接收摄像头的帧数据 需要自己实现的代码只是打开摄像头,写一个SurfaceView进行预览,然后实现PreviewCallback将摄像头每一帧的数据交给javacv即可 javacv地址:https://github.com/bytedeco/javacv demo地址:https://github.com/beautifulSoup/RtmpRecoder/tree/master 二: 使用Android自带的编码工具,可实现硬编码,这里有一个国内大神开源的封装很完善的的库yasea,第一种方法需要实现的Camera采集部分也一起封装好了,进行一些简单配置就可以实现编码推流,并且yasea目前已经直接支持摄像头的热切换,和各种滤镜效果 yasea地址(内置demo):https://github.com/begeekmyfriend/yasea 服务器 流媒体服务器我用的是srs,项目地址:https://github.com/ossrs/srs 关于srs的编译、配置、部署、在官方wiki中已经写的很详细了,并且srs同样是国内开发人员开源的项目,有全中文的文档,看起来很方便 这里有最基本的简单编译部署过程 Android直播实现(二)srs流媒体服务器部署 播放器 android端的播放使用vitamio,还是国内的开源播放器,是不是感觉国内的前辈们越来越屌了^~^! vitamio支持几乎所有常见的的视频格式和流媒体协议 vitamio地址(内置demo):https://github.com/yixia/VitamioBundle 这里使用的是yaesa库,先介绍一下直播实现的流程:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值