本文出自APICloud官方论坛

qiniuLive 封装了七牛直播云服务平台的移动端开放 SDK。该模块包括视频流采集和视频流播放两部分

iOS连麦流程图:

Android连麦流程图:


以下部分代码,仅供参考。

<!DOCTYPE HTML>

<html>

<head>

<meta charset="utf-8">

<meta name="viewport" content="maximum-scale=1.0, minimum-scale=1.0, user-scalable=0, initial-scale=1.0, width=device-width" />

<meta name="format-detection" content="telephone=no, email=no, date=no, address=no">

<title>Hello APP</title>

<link rel="stylesheet" type="text/css" href="../css/api.css" />

<style>

body {

padding-top: 760px;

}

button {

margin: 10px;

}

</style>

</head>

<body>

<p>主播操作</p>

<button type="button" onclick="fnsetStreamingProfile('ddghh')" name="button">initStreamingEnv--setStreamingProfile</button>

<button type="button" onclick="fnstartStream()" name="button">startStream</button>

<button type="button" onclick="fnconfigConference(320)" name="button">configConference</button>

<button type="button" onclick="fnstartConference('ddghh')" name="button">startConference</button>

<p>副主播操作</p>

<button type="button" onclick="fnsetStreamingProfile('vbmuy')" name="button">initStreamingEnv--setStreamingProfile</button>

<button type="button" onclick="fnstartStream()" name="button">startStream</button>

<button type="button" onclick="fnconfigConference(320)" name="button">configConference</button>

<button type="button" onclick="fnstartConference('vbmuy')" name="button">startConference</button>

<p>播放</p>

<button type="button" onclick="fninitPMediaPlayer()" name="button">fninitPMediaPlayer</button>

<button type="button" onclick="fnstart()" name="button">fnstart</button>

</body>

<script type="text/javascript" src="../script/api.js"></script>

<script type="text/javascript">

var room_name, user_id, roomToken;

var qiniuLive;

apiready = function() {

qiniuLive = api.require('qiniuLive');

qiniuLive.initStreamingEnv(function(ret) {

if (ret.status) {

console.log('initStreamingEnv成功' + JSON.stringify(ret));

qiniuLive.addRtcStateDidChangeListener(function(ret) {

console.log('addRtcStateDidChangeListener---' + JSON.stringify(ret));

if (ret.state == 'inited') {

if (api.systemType == "ios") {

fnconfigConference();

//fnstartConference();

}

}

});

qiniuLive.addEventListener({ //流状态已变更事件

name: 'streamStatus'

}, function(ret) {

console.log('streamStatus---' + JSON.stringify(ret));

if (ret.streamStatus == 17) {  //Android适用

fnconfigConference();

}

if (ret.streamStatus == 8) {

}

});

qiniuLive.addRoomOIListener(function(ret) {

console.log('主播进出房间' + JSON.stringify(ret));

if (ret.eventType == "didJoin") {

alert(ret.userID + "进入房间")

}

});

qiniuLive.addRtcDidFailListener(function(ret) {

console.log('错误回调addRtcDidFailListener的监听' + JSON.stringify(ret));

});

}

});

};

// 配置直播流参数,初始化推流预览区域

function fnsetStreamingProfile(pkuid) {

//$api.setStorage('uid', pkuid);

qiniuLive.setStreamingProfile({

rect: {

x: 0,

y: 0,

w: parseInt(api.frameWidth),

h: parseInt(api.frameWidth)

},

remoteWindowRect: [{

x: parseInt(api.frameWidth / 2),

y: 0,

w: parseInt(api.frameWidth / 2),

h: parseInt(api.frameHeight / 2)

}],

pushUrl: 'rtmp://xxxx/****' + pkuid,         //填写自己的推流地址

videoCapture: {

videoFrameRate: 30,

sessionPreset: '100x100',

previewMirrorFrontFacing: true,

previewMirrorRearFacing: false,

streamMirrorFrontFacing: false,

streamMirrorRearFacing: false,

videoOrientation: 'portrait',

cameraPosition: 'front'

},

previewSetting: {

previewSizeLevel: 'small', // 字符类型;相机预览大小等级

// 取值范围:small, medium, large

previewSizeRatio: 'ratio_4_3' // 字符类型;相机预览大小比例 //这个会改变本地的比例大小吗?

// 取值范围:ratio_4_3, ratio_16_9

},

videoStream: {

videoSize: {

width: 960,

height: 640

},

videoQuality: 'low1'

},

localWinPosition: {

x: 0,

y: 0,

w: 480,

h: 640

},

encodeOritation: "landscape",

face: {

beautify: false,

setBeautify: 0,

setWhiten: 0,

setRedden: 0

},

audioQuality: 'medium',

continuousFocus: false,

fixedOn: api.frameName,

fixed: true

}, function(ret) {

if (ret.status) {

console.log('setStreamingProfile成功' + JSON.stringify(ret));

if (api.systemType == "ios") {

console.log('ios-----' + 'setWithServerRegion');

qiniuLive.setWithServerRegion({

serverRegionID: 0

});

}

}

});

}

//开始推流

function fnstartStream() {

qiniuLive.startStream(function(ret) {

if (ret.status == true) {

console.log('推流成功');

} else {

//start_stream();

console.log('推流失败');

}

});

}

//配置连麦

function fnconfigConference(x) {

qiniuLive.configConference({

videoEncodingSizeRatio: 'ratio_4_3',

videoEncodingSize: 480,

videoBitrateRange: {

from: 100 * 1000,

to: 300 * 1000

},

fps: 20,

mixVideoSize: { //默认跟setStreamingProfile接口的videoStream ->videoSize参数保持一致

width: 640,

height: 480

},

localVideoRect: {

x: x, //(可选项)数字类型;x 坐标;默认值:0

y: 0, //(可选项)数字类型;y 坐标;默认值:0

width: 320,

height: 480,

//width: parseInt(api.frameWidth),

//height: parseInt(api.frameHeight)

},

mixOverlayRectArray: [{ //控制观众端的对方画面

x: 480,

y: 0,

w: 480,

h: 640

}

// , {

//         x: 120,

//         y: 120,

//         w: 120,

//         h: 120

// }

],

rejoinTimes: 3,

connetTimeout: 5000

}, function(ret) {

if (ret.status) {

console.log('configConference成功' + JSON.stringify(ret));

fnstartStream();

} else {

console.log('configConference失败');

}

});

}

// 从服务器获取直播房间号、token,然后开始连麦

function fnstartConference(uid) {

api.ajax({

type: 'get',

url: 'http://www/*****/fangjian?uid=' + uid   //填写自己的服务器接口地址

}, function(ret) {

var room = ret.content;

room_name = room.room_name;

roomToken = room.roomToken;

qiniuLive.startConference({

userId: uid,

roomName: room_name,

roomToken: roomToken

}, function(ret, err) {

if (ret) {

console.log('startConference---' + JSON.stringify(ret));

} else {

console.log('startConference---' + JSON.stringify(err));

}

});

})

}

//停止推流、停止连麦

function stopStearm() {

qiniuLive.stopStream(function(ret) {

alert('已停止推流');

});

qiniuLive.stopConference(function(ret) {

//  alert('结束连麦');

});

}

// 初始化播放器,播放端调用

function fninitPMediaPlayer() {

qiniuLive.initPMediaPlayer({

rect: {

x: 0,

y: 0,

w: 320,

h: 480

},

dataUrl: 'rtmp://xxx/*****',     //填写自己的拉流地址

codec: 0,

prepareTimeout: 10000,

readTimeout: 10000,

isLiveStream: true,

isDelayOptimization: true,

cacheBufferDuration: 2000,

maxCacheBufferDuration: 4000,

fixedOn: api.frameName,

fixed: true

}, function(ret) {

alert(JSON.stringify(ret));

});

}

//开始播放,播放端调用

function fnstart() {

qiniuLive.start(function(ret) {

alert(JSON.stringify(ret));

});

}

</script>

</html>

复制代码

qiniuLive 连麦流程介绍的更多相关文章

  1. 转: Annovar 软件注释流程介绍

    第一步:下载Annovar 上Annovar官网下载(http://annovar.openbioinformatics.org/en/latest/user-guide/download/),现在要 ...

  2. 02-FPGA设计流程介绍——小梅哥FPGA设计思想与验证方法视频教程配套文档

    芯航线——普利斯队长精心奉献 课程目标: 1.了解并学会FPGA开发设计的整体流程 2.设计一个二选一选择器并进行功能仿真.时序仿真以及板级验证 实验平台:芯航线FPGA开发板.杜邦线 实验内容: 良 ...

  3. OpenCart框架运行流程介绍

    框架运行流程介绍 这样的一个get请求http://hostname/index.php?route=common/home 发生了什么? 1. 开始执行入口文件index.php. 2. requi ...

  4. UED视觉交互设计与流程介绍

    UED视觉交互设计与流程介绍 ------------------------------------------------------------------ 今天先到这儿,希望对您技术领导力, ...

  5. Solr系列五:solr搜索详解(solr搜索流程介绍、查询语法及解析器详解)

    一.solr搜索流程介绍 1. 前面我们已经学习过Lucene搜索的流程,让我们再来回顾一下 流程说明: 首先获取用户输入的查询串,使用查询解析器QueryParser解析查询串生成查询对象Query ...

  6. shiro原理及其运行流程介绍

    shiro原理及其运行流程介绍 认证执行流程 1.通过ini配置文件创建securityManager 2.调用subject.login方法主体提交认证,提交的token 3.securityMan ...

  7. Zbar算法流程介绍

    博客转载自:https://blog.csdn.net/sunflower_boy/article/details/50783179 zbar算法是现在网上开源的条形码,二维码检测算法,算法可识别大部 ...

  8. iOS蓝牙连接流程介绍-1

    蓝牙连接流程介绍 1.1-程序员找女朋友流程介绍 0.程序员找女朋友参与者 1.你 2.受害者(女性同胞)  (1)她的性格1 性格的特点 (2)她的性格2  分析性格的特点 1.寻找女性 寻尽身边一 ...

  9. 13.1 CentOS系统启动流程介绍

    CentOS系统启动流程介绍 本章我们将学习 Linux 启动流程和内核模块管理相关的内容.通过本章我们将学习如下内容: Linux 系统的组成及特点 CentOS 系统的启动流程 开机启动成 gru ...

随机推荐

  1. Python--day27--几个内置方法:__repr__()/__str__()/__del__()/__call__()/__getitem__/__setitem/delitem/__new__/__eq__/__hash__

    repr方法() 双下方法__str__: 打印对象就相当于打印对象.__str__ __repr__(): __repr__是__str__的备胎,没有__str__的时候,就调用__repr__: ...

  2. JVM基础--JVM参数之堆栈空间配置

    目录 堆配置 年轻代 Eden区 永久代(JDK1.7) 元空间(JDK1.8) 栈空间 直接内存 总结 参考资料 JVM系列目录 JVM 中最重要的一部分就是堆空间了,基本上大多数的线上 JVM 问 ...

  3. 【图数据库】史上超全面的Neo4j使用指南

    转自:https://cloud.tencent.com/developer/article/1336299 在这篇文章中: 第一章:介绍 Neo4j是什么 Neo4j的特点 Neo4j的优点 第二章 ...

  4. 2019-10-23-WPF-使用-SharpDx-异步渲染

    title author date CreateTime categories WPF 使用 SharpDx 异步渲染 lindexi 2019-10-23 21:18:38 +0800 2018-0 ...

  5. Vmware虚拟机用户密码忘记了怎么办?

    Vmware虚拟机用户密码忘记了怎么办?   虚拟机Linux上用户密码忘记了怎么办? 今天准备再学习一下linux操作系统,由于之前已经安装过vaware和linux(redhat),所以这次认为不 ...

  6. Codeforces Beta Round #4 (Div. 2 Only) D. Mysterious Present(LIS)

    传送门 题意: 现在我们有 n 个信封,然后我们有一张卡片,并且我们知道这张卡片的长和宽. 现给出这 n 个信封的长和宽,我们想形成一个链,这条链的长度就是这条链中所含有的信封的数量: 但是需要满足① ...

  7. win10 uwp 使用 LayoutTransformer

    如果需要使用旋转,那么很容易把图片旋转的布局被裁剪.如果需要旋转的控件还在指定的 Grid 内,就需要使用布局的旋转.本文告诉大家如何使用 LayoutTransformer.需要知道,uwp是没有 ...

  8. P1020 从大到小排序

    题目描述 给你n个整数,请你按照从大到小的顺序输出它们. 输入格式 输入的第一行包含一个整数 \(n(1 \le n \le 10^3)\) ,用于表示元素的个数. 输入的第二行包含 \(n\) 个整 ...

  9. The call() and apply() Mtheods

    Example 6-4function classof(o) {     if (o === null) return "Null";     if (o ===undefined ...

  10. ZR1158

    ZR1158 http://www.zhengruioi.com/contest/446/problem/1158 给定限制的问题大多数都是容斥或者二分,或者二分之后容斥 首先,这个问题的第一步我们还 ...