近两年,很多电商平台开始关注起直播互动电商,希望在直播中,也可以增加互动,例如在直播过程中,抛出限量优惠商品,实时发送抢购的消息给观众。于是我们做了一个简单的直播软件源码Demo。

Demo大致的整体想法如下:以视频直播为主的互动模型基础上,结合语音转写功能进行设计,为主播摆脱Windows端繁琐操作,实现快速发题的功能。主播通过语音输入题目(问答题,答案只有是和否),确认后将题目文本发送给所有房间内的观众,观众收到题目后App主动弹框给观众选择结果。

1.1 功能拆解:

  • 只有主播有发布题目入口。
  • 需要ASR(Automatic Speech Recognition-语音识别)功能,有online实时翻译和本地offline翻译两个方案。
  • ASR结果需要主播确认。
  • ASR结果主播确认后需要通知给所有非主播用户。
  • 非主播用户收到题目信息时需要主动弹窗,给用户选择结果。

1.2 方案确定:

  • 为了确保ASR的准确性选择了online实时翻译,通过比对最终选择搜狗知音开放平台。
  • 题目信息也是文本类型,可以借用群聊实时消息通道,给题目信息前面加上特殊字符,非主播用户收到消息时判断是否是以特殊字符开始,如果是remove特殊字符并弹窗显示题目信息。特殊字符定义时可以考虑到扩展性,以后其它类似功能也可以通过该方案来实现。

2.1 视频直播DEMO

一个简单的直播软件源码Demo按以下几个步骤就可以实现了,可以找几个Android设备run一下看看效果,还是相当easy滴。

Step1 SDK集成

SDK还好支持maven依赖,在build.gradle的dependencies模块中加一行就行:

dependencies {
...
implementation 'io.agora.rtc:full-sdk:2.8.1'
}

Step2 直播引擎创建

声网SDK有个重要的类RtcEngine,负责直播功能管理,提供了上/下线、状态监听、音/视频设置等比较丰富的Api,碰到问题时,首先查这个类就对了。创建引擎时APP_ID参数为声网开发平台创建的应用id。

private RtcEngine mRtcEngine;
try {mRtcEngine = RtcEngine.create(context, LiveDefine.APP_ID,
mRtcEventHandler);mRtcEngine.setChannelProfile(Constants.CHANNEL_PROFILE_COMMUNICATION);mRtcEngine.enableAudio(); // 开启音频功能mRtcEngine.enableVideo(); // 开启视频功能
} catch (Exception e) {e.printStackTrace();
}

Step3 直播View关联

角色有主播和观众区分,关联View时有些许区别。ANCHOR_UID为主播用户id,主播端关联View时为自己的用户id,观众端关联view时为观看的主播的用户id。用户系统需要应用自己管理,声网SDK不提供用户管理。

SurfaceView surface = RtcEngine.CreateRendererView(this);
// 主播端View关联
mRtcEngine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
mRtcEngine.enableLocalAudio(true); // 主播端需要打开本地音频
mRtcEngine.setupLocalVideo(new VideoCanvas(surface,
VideoCanvas.RENDER_MODE_HIDDEN, ANCHOR_UID)); // 主播端设置的是本地video
mRtcEngine.startPreview();  //主播需要开启视频预览// 观众端View关联
mRtcEngine.setClientRole(Constants.CLIENT_ROLE_AUDIENCE);
mRtcEngine.enableLocalAudio(false); // 观众端不需要打开本地音频
mRtcEngine.setupRemoteVideo(new VideoCanvas(surface,
VideoCanvas.RENDER_MODE_HIDDEN, ANCHOR_UID)); // 观众端设置的是远端即主播video

Step4 加入房间

加入房间时第一个参数token为当前登录账户对应的token,直播软件源码自己管理,测试时可从传空。第二个参数为频道id,也是由直播软件源码自己管理的。第三个参数为频道名称。最后一个参数为当前登录的账户id

mRtcEngine.joinChannel("", CHANNEL_ID, "CHANNEL_NAME", uid);

Step5 离开房间

// 主播端离开
mRtcEngine.setupLocalVideo(null);
mRtcEngine.stopPreview();
mRtcEngine.leaveChannel();
// 观众端离开
mRtcEngine.setupRemoteVideo(null);
mRtcEngine.leaveChannel();

2.2 消息功能

直播软件源码房间消息功能可以说是相对基础而简单的了,我们选用的是声网实时信息SDK,这是一个独立的工具类SDK,声网将实时消息功能解耦出来,可以给各个场景提供消息支持。群聊实时消息可参考如下步骤:

Step1 依赖配置

dependencies {
...
implementation 'io.agora.rtm:rtm-sdk:1.0.1'
}

Step2 消息引擎创建

// APP_ID同视频互动SDK保持一致即可
private RtmClient mRtmClient;
mRtmClient = RtmClient.createInstance(context, LiveDefine.APP_ID, listener);

Step3 房间消息初始化

创建一个消息频道前需要调一次登录操作,第一个参数为应用账户token,第二个参数为账户标识。

mRtmClient.login("", userId,
new ResultCallback<Void>() {@Overridepublic void onSuccess(Void aVoid) {Log.d(TAG, "rtmClient login success");}@Overridepublic void onFailure(ErrorInfo errorInfo) {Log.d(TAG, "rtmClient login fail : " + errorInfo);}
});

创建消息频道,CHANNEL_ID是一个标识,可以和直播频道不一致,但是建议保持一致:

RtmChannel mRtmChannel;RtmChannelListener rtmListener = new RtmChannelListener(){@Overridepublic void onMessageReceived(RtmMessage var1, RtmChannelMember var2){// 收到消息,自己发送的消息也会有该方法回调,可以通过RtmChannelMember判断发送消息的人是不是自己,如果是不处理本次消息即可。}@Overridepublic void onMemberJoined(RtmChannelMember var1){// 有用户加入,可用来做用户上线消息处理}@Overridepublic void onMemberLeft(RtmChannelMember var1){// 有用户离开,可用来做用户离线消息处理}
};
mRtmChannel = mRtmClient.createChannel(CHANNEL_ID,
rtmListener );;

Step4 发送消息

RtmMessage rtmMessage = mRtmClient.createMessage();
rtmMessage.setText(msg);
mRtmChannel.sendMessage(rtmMessage, callback);

Step5 退出消息频道

可在退出直播房间时,调用该方法。

mRtmChannel.release();

2.3 在线语音翻译

首先也是需要注册账户并创建应用,详见搜狗知音文档中心,实现可参考如下步骤:

Step1 初始化

调用init方法初始化

// 以下信息从知音平台申请获得
private static final String BASE_URL = "api.zhiyin.sogou.com";
private static final String APP_ID = "";
private static final String APP_KEY = "";
private SogoSpeech mSogouSpeech;
private DefaultAudioSource mAudioSource;
private OnSogouAsrListener mListener;public void init(Context context) {ZhiyinInitInfo.Builder builder = new ZhiyinInitInfo.Builder();ZhiyinInitInfo initInfo = builder.setBaseUrl(BASE_URL).setUuid(UUID).setAppid(APP_ID).setAppkey(APP_KEY).create();SogoSpeech.initZhiyinInfo(context, initInfo);SogoSpeechSettings settings = SogoSpeechSettings.shareInstance();settings.setProperty(SpeechConstants.Parameter.ASR_ONLINE_AUDIO_CODING_INT,
1);settings.setProperty(SpeechConstants.Parameter.ASR_ONLINE_VAD_ENABLE_BOOLEAN,
false); settings.setProperty(SpeechConstants.Parameter.ASR_ONLINE_VAD_LONGMODE_BOOLEAN,
true); // 长时间ASRsettings.setProperty(Parameter.ASR_ONLINE_LANGUAGE_STRING,
ASRLanguageCode.CHINESE); // 也支持英文ASR ASRLanguageCode.ENGLISmSogouSpeech = new SogoSpeech(context);mSogouSpeech.registerListener(mSpeechEventListener);mAudioSource = new DefaultAudioSource(new AudioRecordDataProviderFactory(context));mAudioSource.addAudioSourceListener(mAudioSourceListener);
}private EventListener mSpeechEventListener = new EventListener() {@Overridepublic void onEvent(String eventName, String param, byte[] data, int offset, int length, Object extra) {if (TextUtils.equals(SpeechConstants.Message.MSG_ASR_ONLINE_LAST_RESULT,
eventName)) {if (null != mListener) {mListener.onSogouAsrResult(param);}stopTransform();}}@Overridepublic void onError(String errorDomain, int errorCode, String errorDescription, Object extra) {// 9002 用户主动取消if (9002 != errorCode && null != mListener) {mListener.onSogouAsrResult("");}stopTransform();}
};private IAudioSourceListener mAudioSourceListener = new IAudioSourceListener() {@Overridepublic void onBegin(IAudioSource iAudioSource) {Log.d(TAG, "AudioSource onBegin");mSogouSpeech.send(SpeechConstants.Command.ASR_ONLINE_START, "", null, 0, 0);}@Overridepublic void onNewData(IAudioSource audioSource, Object dataArray, long packIndex, long sampleIndex, int flag) {final short[] data = (short[]) dataArray;mSogouSpeech.send(SpeechConstants.Command.ASR_ONLINE_RECOGIZE, "", data, (int) packIndex, 0);}@Overridepublic void onEnd(IAudioSource audioSource, int status, Exception e, long sampleCount) {Log.d(TAG, "AudioSource onEnd");mSogouSpeech.send(SpeechConstants.Command.ASR_ONLINE_STOP, "", null, 0, 0);}
};public interface OnSogouAsrListener {void onSogouAsrResult(String result);
}

Step2 开始语音识别

public void startTransform(OnSogouAsrListener listener) {mListener = listener;mSogouSpeech.send(SpeechConstants.Command.ASR_ONLINE_CREATE,
null, null, 0, 0);new Thread(mAudioSource, "audioRecordSource").start();
}

Step3 停止语音识别

正常情况下直播软件源码不需要调用该方法,在EventListener 回调中已经调用过该方法了,为了确保状态正常也可以在退出房间时手动调用一次。

public void stopTransform() {mListener
= null;if (null != mAudioSource) {mAudioSource.stop();}
}

最后秀一下直播软件源码Demo 实现的效果。
(1)主播端直播发题(语音转文字):

(2)观众端答题

(3)主播端收获答案

以上,就是直播软件源码实现直播互动的内容了。

声明:本文由云豹科技转发自声网Agora博客,如有侵权请联系作者删除

实现简单的直播互动功能,直播软件源码是如何做的相关推荐

  1. PHP编辑留言源码,php实现简单的留言板功能(附源码)

    php实现简单的留言板功能 1.原理 简单的说就是 数据库的创建,添加数据,显示在前端上.我的程序只是简单的留言再显示. 首先写好留言的前端页面,就简单的写入作者,标题和内容. 2.界面: 3.显示留 ...

  2. 直播软件源码,实现一个简单的直播功能

    概述 一直好奇直播软件源码这个东东是如何实现的,譬如音视频流是如何采集的? 音视频流是如何推送到订阅方 ? 如何支撑上万级.百万级用户同时观看直播 ? 功能设计 如上图所示为直播软件源码 Demo 实 ...

  3. 视频交友直播软件源码开发的必备功能讲解

    相信通过这两年行业的发展我们不难看出.视频交友直播源码拥有简单直接的变现方式,深受平台和用户的喜爱,越来越多的年轻人也热衷于视频直播. 视频交友直播软件开发,支持用户在视频过程中用文字沟通,可以互相发 ...

  4. 直播软件源码开发,实现小程序直播的功能

    为了方便用户观看,有些直播软件源码支持小程序端观看,那么小程序的直播软件源码功能如何实现呢,就让我们一起看一下吧. 1.添加直播组件 以mpvue为例 //app.json "plugins ...

  5. 仿比心一对一直播软件源码开发,消息通知功能的实现

    在仿比心一对一直播软件源码中,消息功能起着非常重要的作用,非实时性的社交都可以通过消息功能来实现,在即时消息模块有两个基本功能就是发送消息和接收消息.我们定义如下通信指令来实现这两个功能: Push ...

  6. 直播软件源码如何在Android端实现多人视频通话

    本篇主要讨论直播软件源码如何在Android端实现多人视频通话.主要需要实现以下功能: 随着加入人数和他们的手机摄像头分辨率的变化,显示不同的UI,即所谓的"分屏" 点击分屏中的小 ...

  7. 一对一直播软件源码开发,iOS视频采集的实现过程

    在一对一直播软件源码日益火热的发展形势下,音视频开发(采集.编解码.传输.播放.美颜)等技术也随之成为开发者们关注的重点,本系列文章就音视频开发过程中所运用到的技术和原理进行梳理和总结. 认识 AVC ...

  8. 直播软件源码如何实现直播flash插件

    直播软件源码如何实现直播flash插件 项目搭建 原有的项目是用的layui+jq搭建.现在将大屏部分独立出来: 开心到飞起,哈哈哈 现在大屏单独出来做,我采用了react + react-mobx; ...

  9. 一对一直播软件源码开发,一对一直播怎么开发

    直播行业自2016年的"千播大战",时至今日,直播平台内容同质化现象严重,反倒是一对一直播软件如"雨后春笋"般进入了人们的视野.一对一直播软件源码开发核心业务模 ...

最新文章

  1. Jsoup解析XML
  2. Java反射实现几种方式
  3. 服务器硬件及RAID配置
  4. [2020-11-24 contest]糖果机器(二维偏序),手套(状压dp),甲虫(区间dp),选举(线段树 最大子段和)
  5. 远程执行漏洞修复方案_请马上修复!SaltStack远程命令执行漏洞
  6. Shell编程入门基础上
  7. 在编码中熟练使用JDK文档
  8. UI设计素材|卡券界面设计
  9. 【转】现代浏览器的工作原理
  10. 最简单的基于FFmpeg的移动端例子:Android 视频解码器-单个库版
  11. CodeVs天梯青铜Bronze题解
  12. deeplab v3 ppt_「秋叶PPT」被这件事难倒的张雨绮,撕开了千万职场人最羞愧的一面...
  13. HDU - 5950 Recursive sequence(矩阵快速幂)
  14. 软件工程学习进度第一周暨暑期学习进度之第一周汇总
  15. 倒立摆源代码仿真matlab/simulink神经网络PID(模糊)控制校正LQR 神经网络 倒立摆控制 倒立摆LQR控制仿真 单级倒立摆的模糊控制 旋转倒立摆
  16. elasticsearch之 hdfs上的备份和还原操作
  17. 李南江 html5笔记,Mr.Woo跟着李南江学习HTML5—项目总结
  18. 腾讯 AI Lab 2020 年度回顾
  19. hosts文件的作用说明
  20. jS 清除form表单

热门文章

  1. 【QQ技术】群文件报毒怎样下载?~ 变相绕过QQ复杂检验过程
  2. 如何精准引流?看完这篇文章你将成为高手
  3. P2467 [SDOI2010]地精部落(dp n个数此起彼伏)
  4. android 带刻度的滑动条_Android自定义控件尺子 滚动刻度尺
  5. 6-2 两个字符串穿插 (10 分)
  6. express-session在浏览器中存的connect.sid是加密过的
  7. 股票量化交易SQL特征工程入门
  8. cocos cretor shader effect-the book of shader前言
  9. 单片机 利用C语言产生正弦波DA数据
  10. 教你怎样任意转换视频格式