HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

闭包 作用域 原型链

js
// 代码1  
if(!("userName" in window)) {  
  var userName = "yang"  
}  
console.log(userName) // undefined  
if是一个块,在ES6里有块级作用域,在ES5里是没有这个概念的。  
// 代码2  
var obj = {  
  user: "yang",  
  getName: function () {  
    return this.user;  
  }  
}  
var getNameFn = obj.getName;  
console.log(getNameFn()) // Uncaught ReferenceError: user is not defined  
console.log(obj.getName()) // Uncaught ReferenceError: user is not defined  

var obj = {  
  user: "yang",  
  getName: function () {  
    return this.user;  
  }  
}  
var getNameFn = obj.getName;  
console.log(getNameFn()) // Uncaught ReferenceError: user is not defined  
console.log(obj.getName()) // "yang"  

作用域
1、程序级
2、文件级
3、函数级
4、块级

全局作用域、函数作用域、块级作用域(es6)
js中只有一个局部作用域就是函数作用域

// 代码3  
var global  = 1;  
function doSomething() {  
  var inner = 2;  
 globalA = 3;  
}  
doSomething();  
alert(global);  // 1  
alert(globalA); // 3  
alert(inner);  // undefined

什么是作用域链?
在js中,函数也是对象,函数对象和其他对象一样,拥有可以通过代码访问的属性和一系列仅供js引擎访问的内部函数,其中一个内部属性是【scope】,由ECMA-262标准第三版定义,该内部属性包含了函数被创建作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。

var x = 1;  
function foo () {  
  var y = 1 + x;  
  return function () {  
    var z = 1 + y;  
    return z;  
  }  
}  
foo()();  

// 代码4  
var test = "aa"  
function doSomething() {  
  alert(test) // undefined 变量与函数的声明提前,永远访问不到外部的test  
  var test = "bb"  
  alert(test) // bb  
}  
doSomething()  
alert(test) //aa  

**变量与函数的声明提前**  

function foo () {  
  alert(test);  
  var test = "bb"  
  alert(test)  
}  
foo()  
执行顺序:  
1.声明函数foo  
2. 调用函数foo  
3. 声明变量test  
4. alert(test)  
5.test变量赋值为bb  
6.alert(test)  

js中this关键字
this指向哪里?
在js中,this指向函数执行时的当前对象。
this的使用场景
》普通函数中:
严格模式中:undefined
非严格模式中:全局对象(window)
》构造函数中:对象的实例
》对象方法:对象本身
call、apply、bind
通过这三个方法可以改变被调用函数中this指向的对象

原型对象是什么
在js中,每定义一个对象(函数)时,对象中都会包含一些预定义的属性。其中函数对象的一个属性就是原型对象prototype。普通对象没有prototype属性,但有proto属性

function f1() {};  
console.log(typeof f1.prototype) // Object  
console.log(typeof Function.prototype) // Function,这个特殊  
console.log(typeof Object.prototype) // Object  
console.log(typeof Function.prototype.prototype) //undefined

原型对象有什么用?
面向对象开发、类的继承

function Person(name) {  
  this.name = name;  
}  
Person.prototype.getName = function () {  
  return this.name;  
}  
var sub = new Person("yang")  
sub.getName() //yang

构造函数
使用new关键字调用一个函数的时候,这个函数就叫构造函数
构造函数可以实例化一个对象
返回值,默认返回类的实例
特殊情况:没有返回值、简单数据类型、对象类型
原型链
1.每个函数都有一个prototype的对象属性

  1. 每个对象都有一个 proto 属性,该属性指向其父类的prototype对象
    原型对象中的constructor
    每个原型对象prototype中都有一个constructor属性,默认指向函数本身
    
    // test 1  
    function make(num) {  
    return function () {  
    return num;  
    }  
    }  

var arr = [make(0),make(1),make(2)]
alert(arr[0]()) // 0
alert(arr[1]()) // 1
alert(arr[2]()) // 2

// test 2
var name = "global"
function A(name) {
// 参数name就是一个变量声明
alert(name) // 3
this.name = name
var name = "1" // 这个name完全不影响
}
A.prototype.name = "2" // 在原型链上后调用
var a = new A("3")
alert(a.name) // 3
delete a.name
alert(a.name) // 2

// test 3
function fun (n,o) {
console.log(o)
return {
fun: function(m) {
return fun(m,n) //访问的是最外层的fun,如果要访问return里的fun,一定是XXX.fun(),一定有“.”这个点
}
}
}
var a = fun(0) // undefined
a.fun(1) // 一定是通过这种方法才能访问到对象的fun,而函数fun不同
a.fun(2)
var b = fun(0).fun(1).fun(2).fun(3)
var c = fun(0).fun(1)
c.fun(2)
c.fun(3)
相关说明:https://segmentfault.com/a/1190000004187681
其实是这样的
function _fun (n,o) {
console.log(o)
return {
fun: function(m) {
return _fun(m,n) //访问的是最外层的fun,如果要访问return里的fun,一定是XXX.fun(),一定有“.”这个点
}
}
}


chrome调试作用域链  
闭包就是一个函数一个作用域,使用场景  
使用的i函数就是一个局部作用域,就是一个闭包  
闭包会引起内存泄漏为什么还要用它?  
涉及到js的垃圾回收,循环引用,会在闭包执行完之后进行回收,内存泄漏是认为写代码不当导致的,函数式编程中闭包更常用。  

变量的提前声明  
《函数式编程》  
lodash  
继续阅读 »
// 代码1  
if(!("userName" in window)) {  
  var userName = "yang"  
}  
console.log(userName) // undefined  
if是一个块,在ES6里有块级作用域,在ES5里是没有这个概念的。  
// 代码2  
var obj = {  
  user: "yang",  
  getName: function () {  
    return this.user;  
  }  
}  
var getNameFn = obj.getName;  
console.log(getNameFn()) // Uncaught ReferenceError: user is not defined  
console.log(obj.getName()) // Uncaught ReferenceError: user is not defined  

var obj = {  
  user: "yang",  
  getName: function () {  
    return this.user;  
  }  
}  
var getNameFn = obj.getName;  
console.log(getNameFn()) // Uncaught ReferenceError: user is not defined  
console.log(obj.getName()) // "yang"  

作用域
1、程序级
2、文件级
3、函数级
4、块级

全局作用域、函数作用域、块级作用域(es6)
js中只有一个局部作用域就是函数作用域

// 代码3  
var global  = 1;  
function doSomething() {  
  var inner = 2;  
 globalA = 3;  
}  
doSomething();  
alert(global);  // 1  
alert(globalA); // 3  
alert(inner);  // undefined

什么是作用域链?
在js中,函数也是对象,函数对象和其他对象一样,拥有可以通过代码访问的属性和一系列仅供js引擎访问的内部函数,其中一个内部属性是【scope】,由ECMA-262标准第三版定义,该内部属性包含了函数被创建作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。

var x = 1;  
function foo () {  
  var y = 1 + x;  
  return function () {  
    var z = 1 + y;  
    return z;  
  }  
}  
foo()();  

// 代码4  
var test = "aa"  
function doSomething() {  
  alert(test) // undefined 变量与函数的声明提前,永远访问不到外部的test  
  var test = "bb"  
  alert(test) // bb  
}  
doSomething()  
alert(test) //aa  

**变量与函数的声明提前**  

function foo () {  
  alert(test);  
  var test = "bb"  
  alert(test)  
}  
foo()  
执行顺序:  
1.声明函数foo  
2. 调用函数foo  
3. 声明变量test  
4. alert(test)  
5.test变量赋值为bb  
6.alert(test)  

js中this关键字
this指向哪里?
在js中,this指向函数执行时的当前对象。
this的使用场景
》普通函数中:
严格模式中:undefined
非严格模式中:全局对象(window)
》构造函数中:对象的实例
》对象方法:对象本身
call、apply、bind
通过这三个方法可以改变被调用函数中this指向的对象

原型对象是什么
在js中,每定义一个对象(函数)时,对象中都会包含一些预定义的属性。其中函数对象的一个属性就是原型对象prototype。普通对象没有prototype属性,但有proto属性

function f1() {};  
console.log(typeof f1.prototype) // Object  
console.log(typeof Function.prototype) // Function,这个特殊  
console.log(typeof Object.prototype) // Object  
console.log(typeof Function.prototype.prototype) //undefined

原型对象有什么用?
面向对象开发、类的继承

function Person(name) {  
  this.name = name;  
}  
Person.prototype.getName = function () {  
  return this.name;  
}  
var sub = new Person("yang")  
sub.getName() //yang

构造函数
使用new关键字调用一个函数的时候,这个函数就叫构造函数
构造函数可以实例化一个对象
返回值,默认返回类的实例
特殊情况:没有返回值、简单数据类型、对象类型
原型链
1.每个函数都有一个prototype的对象属性

  1. 每个对象都有一个 proto 属性,该属性指向其父类的prototype对象
    原型对象中的constructor
    每个原型对象prototype中都有一个constructor属性,默认指向函数本身
    
    // test 1  
    function make(num) {  
    return function () {  
    return num;  
    }  
    }  

var arr = [make(0),make(1),make(2)]
alert(arr[0]()) // 0
alert(arr[1]()) // 1
alert(arr[2]()) // 2

// test 2
var name = "global"
function A(name) {
// 参数name就是一个变量声明
alert(name) // 3
this.name = name
var name = "1" // 这个name完全不影响
}
A.prototype.name = "2" // 在原型链上后调用
var a = new A("3")
alert(a.name) // 3
delete a.name
alert(a.name) // 2

// test 3
function fun (n,o) {
console.log(o)
return {
fun: function(m) {
return fun(m,n) //访问的是最外层的fun,如果要访问return里的fun,一定是XXX.fun(),一定有“.”这个点
}
}
}
var a = fun(0) // undefined
a.fun(1) // 一定是通过这种方法才能访问到对象的fun,而函数fun不同
a.fun(2)
var b = fun(0).fun(1).fun(2).fun(3)
var c = fun(0).fun(1)
c.fun(2)
c.fun(3)
相关说明:https://segmentfault.com/a/1190000004187681
其实是这样的
function _fun (n,o) {
console.log(o)
return {
fun: function(m) {
return _fun(m,n) //访问的是最外层的fun,如果要访问return里的fun,一定是XXX.fun(),一定有“.”这个点
}
}
}


chrome调试作用域链  
闭包就是一个函数一个作用域,使用场景  
使用的i函数就是一个局部作用域,就是一个闭包  
闭包会引起内存泄漏为什么还要用它?  
涉及到js的垃圾回收,循环引用,会在闭包执行完之后进行回收,内存泄漏是认为写代码不当导致的,函数式编程中闭包更常用。  

变量的提前声明  
《函数式编程》  
lodash  
收起阅读 »

支持mui的vue脚手架,可下载apk体验,支持ES6/7/8,支持多页面打包

Vue

mogoH5+ v0.2 脚手架发布啦,支持vue,多页面,ES6/7/8,压缩/打包,完全支持mui.可以下载体验apk
体验apk:https://fir.im/p52j
脚手架地址:https://github.com/tyaqing/mogo-h5plus
欢迎各位提出宝贵意见

  • 支持 Npm 生态
  • 支持 vue 语法,以及 vue 生态,比如 vux,mint,vant
  • 支持 ES6/ES7 语法
  • 使用 VConsole 调试
  • VSCode 友好
  • 局域网便捷调试,不插数据线也可以调试
  • 支持mui的使用
继续阅读 »

mogoH5+ v0.2 脚手架发布啦,支持vue,多页面,ES6/7/8,压缩/打包,完全支持mui.可以下载体验apk
体验apk:https://fir.im/p52j
脚手架地址:https://github.com/tyaqing/mogo-h5plus
欢迎各位提出宝贵意见

  • 支持 Npm 生态
  • 支持 vue 语法,以及 vue 生态,比如 vux,mint,vant
  • 支持 ES6/ES7 语法
  • 使用 VConsole 调试
  • VSCode 友好
  • 局域网便捷调试,不插数据线也可以调试
  • 支持mui的使用
收起阅读 »

老帖子已经关闭

phpgrace PHP

老帖子已经关闭

老帖子已经关闭

h5+、mui、app开发基础+实战教程都在这儿!

mui h5+


《JavaScript 快速提高视频教程》 js基础快速提高课程 【免费】
http://www.hcoder.net/course/info_229.html

《MUI 视频教程》【免费】
http://www.hcoder.net/course/info_211.html

《h.js 视频教程》【免费】
http://www.hcoder.net/tutorials/info_147.html

《HTML 5 开发教程》【免费】
http://www.hcoder.net/course/info_212.html

《APP开发实例教程 - 窗口切换 》【免费】
http://www.hcoder.net/course/info_218.html

《HBuilder 8.0.1 APP开发 - 新功能全接触》【免费】
http://www.hcoder.net/course/info_227.html

--------- 实战收费教程 ------------------------
《仿腾讯新闻客户端》- MUI+VUE.JS H5+ APP 实战教程
http://www.hcoder.net/course/info_240.html

MUI、H5 APP 实战教程 - 仿《有道词典》
https://ke.qq.com/course/194834

H5 跨平台APP开发电商项目实战教程 -《仿京东优选商城》
https://ke.qq.com/course/225830

更多课程中心
http://www.hcoder.net/course

继续阅读 »


《JavaScript 快速提高视频教程》 js基础快速提高课程 【免费】
http://www.hcoder.net/course/info_229.html

《MUI 视频教程》【免费】
http://www.hcoder.net/course/info_211.html

《h.js 视频教程》【免费】
http://www.hcoder.net/tutorials/info_147.html

《HTML 5 开发教程》【免费】
http://www.hcoder.net/course/info_212.html

《APP开发实例教程 - 窗口切换 》【免费】
http://www.hcoder.net/course/info_218.html

《HBuilder 8.0.1 APP开发 - 新功能全接触》【免费】
http://www.hcoder.net/course/info_227.html

--------- 实战收费教程 ------------------------
《仿腾讯新闻客户端》- MUI+VUE.JS H5+ APP 实战教程
http://www.hcoder.net/course/info_240.html

MUI、H5 APP 实战教程 - 仿《有道词典》
https://ke.qq.com/course/194834

H5 跨平台APP开发电商项目实战教程 -《仿京东优选商城》
https://ke.qq.com/course/225830

更多课程中心
http://www.hcoder.net/course

收起阅读 »

直播业务指南

video 直播

*注意要使用HBuilderX而不是HBuilder

引言

直播是很多开发者的需求。
HTML5的video,虽然可以播放流媒体,但不支持rtmp等常用直播格式。更无法实现推流,就是实时流式上传视频。
5+App、uni-app给开发者提供了完整的直播解决方案。
HTML5Plus规范提供了plus.video扩展规范,实现了原生的视频播放和推流录制上传。

HTML5Plus的规范是通行规范,可支持任何直播云服务厂商的直播服务器。
但又拍云公司作为HTML5中国产业联盟成员,为HTML5plus的开发者提供了更多完善服务。

  1. 注册优惠
    点此链接注册,可得众多优惠。
    a) 认证完毕后赠送 61 元免费代金券;
    b) 首次充值后,奖励充值金额 10% 代金券
    c) 一周后再赠送200元的代金劵
    以上优惠不是三选一,是全都有。有效期1个月时间。
  2. 便捷的服务器搭建
    无需关心rtmp服务器的搭建和网络cdn的优化,注册后提供自己的直播推流和播放的域名,做cname映射到又拍云的服务器,然后自己随便定义二级目录地址就可以用了。
    详见又拍云文档http://docs.upyun.com/live/guide/

代码示例-推流上传(live-pusher)

直播推流控件会调用手机摄像头采集视频流,编码后通过rtmp协议提交到直播服务器。

并实现了一套代码兼容App和小程序,具体参考上述组件及API文档。

  1. uni-app下的vue页面
    app平台的vue页面中使用直播推流,不能使用uni的api,而需要使用plus的API

    const currentWebview = this.$mp.page.$getAppWebview()  
    var pusher = plus.video.createLivePusher("", {    
    url:'rtmp://testlivesdk.v0.upaiyun.com/live/upyunb',    
    top:'100px',    
    left:'0px',    
    width: '100%',    
    height: '300px',    
    position: 'static'    
    });    
    currentWebview.append(pusher);  
  2. 5+App模式示例:
    在页面中直播推流控件需要绑定div确定位置及大小,创建直播推流控件需要传入div的id,示例如下:

    <html>  
       <head>  
              <meta charset="utf-8"/>  
              <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>  
              <title>Hello H5+</title>  
              <script type="text/javascript">  
    var pusher = null;  
    // H5 plus事件处理  
    function plusReady(){  
       // 创建直播推流控件  
       pusher = new plus.video.LivePusher('pusher',{url:'rtmp://testlivesdk.v0.upaiyun.com/live/upyunb'});  
       // 监听状态变化事件  
       pusher.addEventListener('statechange', function(e){  
              console.log('statechange: '+JSON.stringify(e));  
       }, false);  
    }  
    document.addEventListener('plusready', plusReady, false);  
              </script>  
       </head>  
       <body>  
              <br/>  
              <div id="pusher" style="width:300px;height:400px;background-color:#000000;margin:auto"></div>  
       </body>  
    </html>

    其中new plus.video.LivePusher()第一个参数'pusher'为绑定div的id值,第二个参数中的url属性值为直播推流服务器地址,必须为rtmp协议。创建后返回直播推流控件(LivePusher)对象,后续可通过此对象进行操作控制。

使用HBuilderX新建5+App项目时自带的Hello H5+模板,真机运行,可以看到video示例,里面有推流和播放的示例代码。

  • 采集直播推流提交到服务器
    创建直播推流控件后可通过setOptions方法更新直播控件参数,如下更新直播推流服务器地址:
    pusher.setOptions({url:'rtmp://新的直播推流服务器地址'});

    配置完成后调用start方法开始采集直播流提交到服务器:

    pusher.start();

推流时支持美颜、摄像头切换。不支持其他特效滤镜。
目前不支持录屏直播,无法实现手机录制。除非使用原生sdk自行开发离线打包。
目前暂不支持直播连麦功能。

更多API参考文档http://www.html5plus.org/doc/zh_cn/video.html#plus.video.LivePusher
推流到直播服务器后可通过原生视频播放控件进行播放。

代码示例-使用视频播放控件播放直播视频流

HTML5标准的video是无法播放直播视频流的,所以需要使用原生增加的播放控件。
HTML5plus扩展的原生视频播放控件(也是uni-app的App端自带的)支持视频格式包括mp4和flv,视频传输协议支持http/https和rtmp/hls/rtsp(直播流)

  • 创建视频播放控件

    1. uni-app模式
      uni-app模式直接使用<video>组件进行播放,无需其他复杂设置。
    2. 5+App模式
      在页面中视频播放控件需要绑定div确定位置及大小,创建视频播放控件需要传入div的id,示例如下:
      <!DOCTYPE HTML>  
      <html>  
      <head>  
            <meta charset="utf-8"/>  
            <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>  
            <title>Hello H5+</title>  
            <script type="text/javascript">  
      var video = null;  
      // H5 plus事件处理  
      function plusReady(){  
      // 创建视频播放控件  
      video = new plus.video.VideoPlayer('video',{  
            src:'rtmp://live.hkstv.hk.lxdns.com/live/hks'  
      });  
      }  
      document.addEventListener('plusready', plusReady, false);  
            </script>  
      </head>  
      <body>  
            <br/>  
            <div id="video" style="width:98%;height:300px;background-color:#000000;margin:auto"></div>  
      </body>  
      </html>

      其中new plus.video.VideoPlayer()第一个参数'video'为绑定div的id值,第二个参数中的src属性值为要播放的直播视频地址,直播视频必须为rtmp协议。创建后返回视频播放控件(VideoPlayer)对象,后续可通过此对象进行操作控制。

  • 播放视频流
    创建视频播放控件后可通过setOptions方法更新播放控件参数,如下更新视频服务器地址:

    video.setOptions({src:'新的视频服务器地址'});

    用户可以点击播放控件上的播放按钮进行播放,也可调用play方法进行播放:

    video.play();

如果想在视频上绘制一些内容,比如滚动的聊天记录,5+App可以在上面创建一个透明webview,具体代码在Hello H5+的video示例里有;uni-app可以在上面创建一个subnvue,在HBuilderX1.9.10+版本中自带的hello uni-app - API - 界面 - 原生子窗体中也有示例。

包括防盗播的跑马灯也可以这么做。

更多API参考文档http://www.html5plus.org/doc/zh_cn/video.html#plus.video.VideoPlayer

三方示例模板

这个是插件市场里三方开发者做的直播业务模板,开源,可以参考:http://ext.dcloud.net.cn/plugin?id=226

还有一些开发者封装了三方原生sdk,比如腾讯直播sdk,可以在插件市场获取

继续阅读 »

*注意要使用HBuilderX而不是HBuilder

引言

直播是很多开发者的需求。
HTML5的video,虽然可以播放流媒体,但不支持rtmp等常用直播格式。更无法实现推流,就是实时流式上传视频。
5+App、uni-app给开发者提供了完整的直播解决方案。
HTML5Plus规范提供了plus.video扩展规范,实现了原生的视频播放和推流录制上传。

HTML5Plus的规范是通行规范,可支持任何直播云服务厂商的直播服务器。
但又拍云公司作为HTML5中国产业联盟成员,为HTML5plus的开发者提供了更多完善服务。

  1. 注册优惠
    点此链接注册,可得众多优惠。
    a) 认证完毕后赠送 61 元免费代金券;
    b) 首次充值后,奖励充值金额 10% 代金券
    c) 一周后再赠送200元的代金劵
    以上优惠不是三选一,是全都有。有效期1个月时间。
  2. 便捷的服务器搭建
    无需关心rtmp服务器的搭建和网络cdn的优化,注册后提供自己的直播推流和播放的域名,做cname映射到又拍云的服务器,然后自己随便定义二级目录地址就可以用了。
    详见又拍云文档http://docs.upyun.com/live/guide/

代码示例-推流上传(live-pusher)

直播推流控件会调用手机摄像头采集视频流,编码后通过rtmp协议提交到直播服务器。

并实现了一套代码兼容App和小程序,具体参考上述组件及API文档。

  1. uni-app下的vue页面
    app平台的vue页面中使用直播推流,不能使用uni的api,而需要使用plus的API

    const currentWebview = this.$mp.page.$getAppWebview()  
    var pusher = plus.video.createLivePusher("", {    
    url:'rtmp://testlivesdk.v0.upaiyun.com/live/upyunb',    
    top:'100px',    
    left:'0px',    
    width: '100%',    
    height: '300px',    
    position: 'static'    
    });    
    currentWebview.append(pusher);  
  2. 5+App模式示例:
    在页面中直播推流控件需要绑定div确定位置及大小,创建直播推流控件需要传入div的id,示例如下:

    <html>  
       <head>  
              <meta charset="utf-8"/>  
              <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>  
              <title>Hello H5+</title>  
              <script type="text/javascript">  
    var pusher = null;  
    // H5 plus事件处理  
    function plusReady(){  
       // 创建直播推流控件  
       pusher = new plus.video.LivePusher('pusher',{url:'rtmp://testlivesdk.v0.upaiyun.com/live/upyunb'});  
       // 监听状态变化事件  
       pusher.addEventListener('statechange', function(e){  
              console.log('statechange: '+JSON.stringify(e));  
       }, false);  
    }  
    document.addEventListener('plusready', plusReady, false);  
              </script>  
       </head>  
       <body>  
              <br/>  
              <div id="pusher" style="width:300px;height:400px;background-color:#000000;margin:auto"></div>  
       </body>  
    </html>

    其中new plus.video.LivePusher()第一个参数'pusher'为绑定div的id值,第二个参数中的url属性值为直播推流服务器地址,必须为rtmp协议。创建后返回直播推流控件(LivePusher)对象,后续可通过此对象进行操作控制。

使用HBuilderX新建5+App项目时自带的Hello H5+模板,真机运行,可以看到video示例,里面有推流和播放的示例代码。

  • 采集直播推流提交到服务器
    创建直播推流控件后可通过setOptions方法更新直播控件参数,如下更新直播推流服务器地址:
    pusher.setOptions({url:'rtmp://新的直播推流服务器地址'});

    配置完成后调用start方法开始采集直播流提交到服务器:

    pusher.start();

推流时支持美颜、摄像头切换。不支持其他特效滤镜。
目前不支持录屏直播,无法实现手机录制。除非使用原生sdk自行开发离线打包。
目前暂不支持直播连麦功能。

更多API参考文档http://www.html5plus.org/doc/zh_cn/video.html#plus.video.LivePusher
推流到直播服务器后可通过原生视频播放控件进行播放。

代码示例-使用视频播放控件播放直播视频流

HTML5标准的video是无法播放直播视频流的,所以需要使用原生增加的播放控件。
HTML5plus扩展的原生视频播放控件(也是uni-app的App端自带的)支持视频格式包括mp4和flv,视频传输协议支持http/https和rtmp/hls/rtsp(直播流)

  • 创建视频播放控件

    1. uni-app模式
      uni-app模式直接使用<video>组件进行播放,无需其他复杂设置。
    2. 5+App模式
      在页面中视频播放控件需要绑定div确定位置及大小,创建视频播放控件需要传入div的id,示例如下:
      <!DOCTYPE HTML>  
      <html>  
      <head>  
            <meta charset="utf-8"/>  
            <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>  
            <title>Hello H5+</title>  
            <script type="text/javascript">  
      var video = null;  
      // H5 plus事件处理  
      function plusReady(){  
      // 创建视频播放控件  
      video = new plus.video.VideoPlayer('video',{  
            src:'rtmp://live.hkstv.hk.lxdns.com/live/hks'  
      });  
      }  
      document.addEventListener('plusready', plusReady, false);  
            </script>  
      </head>  
      <body>  
            <br/>  
            <div id="video" style="width:98%;height:300px;background-color:#000000;margin:auto"></div>  
      </body>  
      </html>

      其中new plus.video.VideoPlayer()第一个参数'video'为绑定div的id值,第二个参数中的src属性值为要播放的直播视频地址,直播视频必须为rtmp协议。创建后返回视频播放控件(VideoPlayer)对象,后续可通过此对象进行操作控制。

  • 播放视频流
    创建视频播放控件后可通过setOptions方法更新播放控件参数,如下更新视频服务器地址:

    video.setOptions({src:'新的视频服务器地址'});

    用户可以点击播放控件上的播放按钮进行播放,也可调用play方法进行播放:

    video.play();

如果想在视频上绘制一些内容,比如滚动的聊天记录,5+App可以在上面创建一个透明webview,具体代码在Hello H5+的video示例里有;uni-app可以在上面创建一个subnvue,在HBuilderX1.9.10+版本中自带的hello uni-app - API - 界面 - 原生子窗体中也有示例。

包括防盗播的跑马灯也可以这么做。

更多API参考文档http://www.html5plus.org/doc/zh_cn/video.html#plus.video.VideoPlayer

三方示例模板

这个是插件市场里三方开发者做的直播业务模板,开源,可以参考:http://ext.dcloud.net.cn/plugin?id=226

还有一些开发者封装了三方原生sdk,比如腾讯直播sdk,可以在插件市场获取

收起阅读 »

免费赠送前端各种学习资料

ajax jquery nodejs Vue

1:微信小游戏入门与实战 点击跳转

2:黑马程序员_node.js视屏教程详解(内含所有源码) 点击跳转

3:jQuery基础视频集合 点击跳转

4:黑马程序员_2018版Ajax教程精讲 点击跳转

5:黑马程序员_2018版Html5+Css3由浅入深 点击跳转

6:黑马程序员_canvas详解 点击跳转

7:黑马程序员_电商实战项目视频(含源码) 点击跳转

8:黑马程序员_ 2018移动web进阶教程 点击跳转

9:ajax详解_视屏教程 点击跳转

10:vue详解 点击跳转

11:毕向东JavaScript视频教程 点击跳转

12:黑马程序员_超全面的javaWeb视频教程点击跳转

13:黑马程序员-JavaScript-高级视频点击跳转

14:黑马程序员:reactjs精品教程视频点击跳转

15:传智播客-黑马程序员最新视频:轻松玩转微信小程序点击跳转

16:vue 2.0 入门及到实战开发点击跳转

继续阅读 »

1:微信小游戏入门与实战 点击跳转

2:黑马程序员_node.js视屏教程详解(内含所有源码) 点击跳转

3:jQuery基础视频集合 点击跳转

4:黑马程序员_2018版Ajax教程精讲 点击跳转

5:黑马程序员_2018版Html5+Css3由浅入深 点击跳转

6:黑马程序员_canvas详解 点击跳转

7:黑马程序员_电商实战项目视频(含源码) 点击跳转

8:黑马程序员_ 2018移动web进阶教程 点击跳转

9:ajax详解_视屏教程 点击跳转

10:vue详解 点击跳转

11:毕向东JavaScript视频教程 点击跳转

12:黑马程序员_超全面的javaWeb视频教程点击跳转

13:黑马程序员-JavaScript-高级视频点击跳转

14:黑马程序员:reactjs精品教程视频点击跳转

15:传智播客-黑马程序员最新视频:轻松玩转微信小程序点击跳转

16:vue 2.0 入门及到实战开发点击跳转

收起阅读 »

ios离线打包后界面包括字体变大

Webview iOS打包 App离线打包

其实这个原因我也找了很多论坛上的帖子,
刚开始以为是不是改了配置什么的东西,
通过各个帖子来看,有说启动图片被替换后导致的,也有说各种原因 ,我觉得这个应该是没用定数的,
通过之前打包ios的sdk进行对比,
发现,还真有一张图片被替换掉了,再把先前打包的那张图片换回来 正常了
究其原因 还是各个细节没有做好,很多遗漏性的问题或者被忘记

这是这个变大的截图

这是正常的截图

首先 出现这个问题 不会是html代码和css样式的问题 很肯定
刚开始也怀疑过是ios的sdk更新了的原因

附上其他人的已解决问题:

iphone6 webview中字体被放大显示,safari中查看正常没有放大

【问题已经解决】好像不止是字体变大了,图片也变大了……

继续阅读 »

其实这个原因我也找了很多论坛上的帖子,
刚开始以为是不是改了配置什么的东西,
通过各个帖子来看,有说启动图片被替换后导致的,也有说各种原因 ,我觉得这个应该是没用定数的,
通过之前打包ios的sdk进行对比,
发现,还真有一张图片被替换掉了,再把先前打包的那张图片换回来 正常了
究其原因 还是各个细节没有做好,很多遗漏性的问题或者被忘记

这是这个变大的截图

这是正常的截图

首先 出现这个问题 不会是html代码和css样式的问题 很肯定
刚开始也怀疑过是ios的sdk更新了的原因

附上其他人的已解决问题:

iphone6 webview中字体被放大显示,safari中查看正常没有放大

【问题已经解决】好像不止是字体变大了,图片也变大了……

收起阅读 »

[通知]云端打包校验应用属主权限

协作者 云端打包

为规范应用管理,避免appid滥用导致的广告误开等问题,自2018.06.22起新建appid,申请云端打包时会校验appid属主及协作者权限,若权限不满足,则不允许打包。

因此,若你的App是多人协作,你需要将相关同事加入协作者并赋予“云端打包”权限,否则除你之外,其它同事将无法对该App进行打包;设置协作者方法参考教程

若App为企业应用,且是员工个人账号创建的,员工离职时,需要将该应用转让给公司账号或交接的同事账号;转让应用方法参考教程

本次改造仅针对2018.06.22后新建的appid,适用于5+App、wap2app、uni-app类型应用;在此之前创建的应用,我们也会逐步梳理,建议开发者提前设置协作者,避免影响自己的收益或用户体验。

如依旧存在困惑,可以单独发帖详细说明情况。如需更多帮助,请发送邮件至 service@dcloud.io。

继续阅读 »

为规范应用管理,避免appid滥用导致的广告误开等问题,自2018.06.22起新建appid,申请云端打包时会校验appid属主及协作者权限,若权限不满足,则不允许打包。

因此,若你的App是多人协作,你需要将相关同事加入协作者并赋予“云端打包”权限,否则除你之外,其它同事将无法对该App进行打包;设置协作者方法参考教程

若App为企业应用,且是员工个人账号创建的,员工离职时,需要将该应用转让给公司账号或交接的同事账号;转让应用方法参考教程

本次改造仅针对2018.06.22后新建的appid,适用于5+App、wap2app、uni-app类型应用;在此之前创建的应用,我们也会逐步梳理,建议开发者提前设置协作者,避免影响自己的收益或用户体验。

如依旧存在困惑,可以单独发帖详细说明情况。如需更多帮助,请发送邮件至 service@dcloud.io。

收起阅读 »

hbuilder开发安卓发布APP到谷歌市场的问题汇总

横竖屏 应用内支付 应用发布 授权 混合开发

分享一下在发布谷歌市场时候遇到的坑。
1.首先mui hbuilder云打包的不是8.0 而谷歌市场必须要求8.0及以上版本打包,所以得下载android studio 混合开发。

2.在混合开发中需要用官方的SDKdemo。 使用官方的SDK demo按教程进行修改。(注意: 看了一下官方的demo 得和AndroidManifest.xml文件里的包名一致。 官方离线打包的说明没特别说明这个地方,而且貌似还误导了,让和hbuilder里面的一样了。)

3.关于谷歌内购 ,还是得需要用到一个插件billingclient https://gitee.com/tjbaobao/GoogleBuillingUtil

4.然后就是安卓6.0以上的动态授权问题:用这个插件搞定 compile 'me.weyye.hipermission:library:1.0.3'

5.然后就是横竖屏幕问题,因为安卓横竖屏幕切换会自动重新加载webview,这个问题百度有详细,我们又重写不了官方sdk里面的代码,所以hbuilder这个混合开发方式怎么办,只能先锁定竖屏plus.screen.lockOrientation("portrait-primary");,然后在需要横屏的地方用样式来旋转页面90度。

继续阅读 »

分享一下在发布谷歌市场时候遇到的坑。
1.首先mui hbuilder云打包的不是8.0 而谷歌市场必须要求8.0及以上版本打包,所以得下载android studio 混合开发。

2.在混合开发中需要用官方的SDKdemo。 使用官方的SDK demo按教程进行修改。(注意: 看了一下官方的demo 得和AndroidManifest.xml文件里的包名一致。 官方离线打包的说明没特别说明这个地方,而且貌似还误导了,让和hbuilder里面的一样了。)

3.关于谷歌内购 ,还是得需要用到一个插件billingclient https://gitee.com/tjbaobao/GoogleBuillingUtil

4.然后就是安卓6.0以上的动态授权问题:用这个插件搞定 compile 'me.weyye.hipermission:library:1.0.3'

5.然后就是横竖屏幕问题,因为安卓横竖屏幕切换会自动重新加载webview,这个问题百度有详细,我们又重写不了官方sdk里面的代码,所以hbuilder这个混合开发方式怎么办,只能先锁定竖屏plus.screen.lockOrientation("portrait-primary");,然后在需要横屏的地方用样式来旋转页面90度。

收起阅读 »

开发入门篇:你会Pick小程序还是App?其实他们合体更互补!

移动APP

移动互联网时代,传统行业翻身,到底该pick小程序,还是App?这成为了众多企业家和创业者的入门疑惑。实质上,我们都进入了App和小程序必须要厮杀到底的误区。那么到底,为什么说小程序和App合体更为互补呢?

App pk 小程序,开发前必须知道的事儿

  1. App重功能,小程序更适合于社交轻量化的尝试
。

App能够实现功能复杂、交互繁琐的重服务,而小程序则更专注以“轻”服务满足用户。
一重一轻,用户体验能达到良好的平衡。

  1. App适合深度用户运营,小程序则更适用于引流

小程序依靠微信助力,其前途无可限量,10亿流量成为了其快速扩张势力的极大本金。因此,不少高频需求的产品,纷纷下海做起了小程序,并且业绩可嘉。
另一方面,App虽然没有流量大树撑腰,但是从长远发展的角度来看,它能沉淀用户到平台,方便企业进行深度的用户运营。既能不断开发用户价值,又能为平台不断累积忠实用户,为后续发展打下坚实基础。
一引一收,流量层层沉淀,方可厚积薄发。
3.App使用路径短,小程序使用门槛低

App的使用路径更短,只需下载 > 安装 > 打开应用 > 使用,更方便经常打开App的用户使用习惯。并且,安卓手机用户很少会将小程序添加到桌面。
与此相比,小程序无需下载,随开随用。但是,需要先打开微信 > 搜索小程序 > 打开小程序,最后才能进行使用,从便捷度上,反而不如App。
归根结底,综合使用频次以及便捷度,一短一低,真正方便用户的才是王道。
4.App无惧中心化,小程序推广成本低

其实,企业只要萌生了做平台的想法,无非一有资源,二有人脉。早已颇有远见的电商企业又怎会坐等被平台宰割?自然是去了中心化(如淘宝天猫等),化去一切条条框框的商业枷锁,自己为自己做嫁衣,方为上策。因而,App可以说是企业打造专属平台的首选产品。
而小程序则全然不同,它有着天然的微信助力,以及背后企鹅爸爸的加持,其引流成本低廉,无需推广即可获客,深受企业方青睐。并且,小程序无广告,用户体验更好。但是,随着小程序的扩张,其商业框架势必要加重,企业仅靠小程序的确能发家,但从长远来看,为免会因腾讯捉襟见肘。
一松一紧,张弛有度,才能酝酿商业佳绩。
聊了这么多,想必大家都有一个共识。为什么我们要以不惜自伤手足的方式,去轻易地干掉App或者小程序任意一个平台呢?的确,他们各有长短,各具优势,其商业价值并非是毫无互联网试水经验者所能简单评估的。着眼企业的长远利益,想必,谁都不想把鸡蛋全放在同一个篮子中吧。毕竟,三十年河东,三十年河西,移动互联网变化如此之快,每个平台的优势都在瞬息万变,企业家应当如何抉择呢?
力谱云给出的答案是,全渠道的移动解决方案。

通过力谱云平台,即可打通App、小程序、微官网、移动网站的任督二脉,全渠道开启移动蓝海之旅,并可进行全局统筹运营,管理更轻松,成本更节省。
力谱云不做单纯的App开发,凭借着多年开发&市场经验的沉淀,我们会为每个企业,依据其市场动态以及企业需求,量身打造最适合企业的移动解决方案。并且,依靠“SaaS+PaaS”创新云计算模式,我们在性价比方面更是业内的一枝独秀。
力谱云功能强大,支持企业构建B2C、B2B、B2B2C、OMO等复杂业务平台,现已重磅推出云集分销、拼多多、生鲜/外卖配送、新渠道裂变等多种解决方案。
力谱云营销功能给力,拼团、多级分销、秒杀、满减优惠、代金券等每月不断迭代更新;更支持功能无限拓展,全面满足企业个性化开发需求。
此外,通过强大的大数据分析,企业即可精准分析用户、商品等数据,有效制定营销战略方针。
总而言之,力谱云通过全渠道获客、高效销售变现、全场景运营、精准分析和优化,为企业从研发到运营、营销、销售,开启全程护航之路。
入海互联网,选择力谱云,打造你的专属移动电商王国吧!

继续阅读 »

移动互联网时代,传统行业翻身,到底该pick小程序,还是App?这成为了众多企业家和创业者的入门疑惑。实质上,我们都进入了App和小程序必须要厮杀到底的误区。那么到底,为什么说小程序和App合体更为互补呢?

App pk 小程序,开发前必须知道的事儿

  1. App重功能,小程序更适合于社交轻量化的尝试
。

App能够实现功能复杂、交互繁琐的重服务,而小程序则更专注以“轻”服务满足用户。
一重一轻,用户体验能达到良好的平衡。

  1. App适合深度用户运营,小程序则更适用于引流

小程序依靠微信助力,其前途无可限量,10亿流量成为了其快速扩张势力的极大本金。因此,不少高频需求的产品,纷纷下海做起了小程序,并且业绩可嘉。
另一方面,App虽然没有流量大树撑腰,但是从长远发展的角度来看,它能沉淀用户到平台,方便企业进行深度的用户运营。既能不断开发用户价值,又能为平台不断累积忠实用户,为后续发展打下坚实基础。
一引一收,流量层层沉淀,方可厚积薄发。
3.App使用路径短,小程序使用门槛低

App的使用路径更短,只需下载 > 安装 > 打开应用 > 使用,更方便经常打开App的用户使用习惯。并且,安卓手机用户很少会将小程序添加到桌面。
与此相比,小程序无需下载,随开随用。但是,需要先打开微信 > 搜索小程序 > 打开小程序,最后才能进行使用,从便捷度上,反而不如App。
归根结底,综合使用频次以及便捷度,一短一低,真正方便用户的才是王道。
4.App无惧中心化,小程序推广成本低

其实,企业只要萌生了做平台的想法,无非一有资源,二有人脉。早已颇有远见的电商企业又怎会坐等被平台宰割?自然是去了中心化(如淘宝天猫等),化去一切条条框框的商业枷锁,自己为自己做嫁衣,方为上策。因而,App可以说是企业打造专属平台的首选产品。
而小程序则全然不同,它有着天然的微信助力,以及背后企鹅爸爸的加持,其引流成本低廉,无需推广即可获客,深受企业方青睐。并且,小程序无广告,用户体验更好。但是,随着小程序的扩张,其商业框架势必要加重,企业仅靠小程序的确能发家,但从长远来看,为免会因腾讯捉襟见肘。
一松一紧,张弛有度,才能酝酿商业佳绩。
聊了这么多,想必大家都有一个共识。为什么我们要以不惜自伤手足的方式,去轻易地干掉App或者小程序任意一个平台呢?的确,他们各有长短,各具优势,其商业价值并非是毫无互联网试水经验者所能简单评估的。着眼企业的长远利益,想必,谁都不想把鸡蛋全放在同一个篮子中吧。毕竟,三十年河东,三十年河西,移动互联网变化如此之快,每个平台的优势都在瞬息万变,企业家应当如何抉择呢?
力谱云给出的答案是,全渠道的移动解决方案。

通过力谱云平台,即可打通App、小程序、微官网、移动网站的任督二脉,全渠道开启移动蓝海之旅,并可进行全局统筹运营,管理更轻松,成本更节省。
力谱云不做单纯的App开发,凭借着多年开发&市场经验的沉淀,我们会为每个企业,依据其市场动态以及企业需求,量身打造最适合企业的移动解决方案。并且,依靠“SaaS+PaaS”创新云计算模式,我们在性价比方面更是业内的一枝独秀。
力谱云功能强大,支持企业构建B2C、B2B、B2B2C、OMO等复杂业务平台,现已重磅推出云集分销、拼多多、生鲜/外卖配送、新渠道裂变等多种解决方案。
力谱云营销功能给力,拼团、多级分销、秒杀、满减优惠、代金券等每月不断迭代更新;更支持功能无限拓展,全面满足企业个性化开发需求。
此外,通过强大的大数据分析,企业即可精准分析用户、商品等数据,有效制定营销战略方针。
总而言之,力谱云通过全渠道获客、高效销售变现、全场景运营、精准分析和优化,为企业从研发到运营、营销、销售,开启全程护航之路。
入海互联网,选择力谱云,打造你的专属移动电商王国吧!

收起阅读 »

分享 Android Studio 离线打包 阿里云 短视频 SDK 基础版

短视频 SDK 离线打包 录制视频

离线打包一些第三方的SDK, 犹如一名战士穿上铠甲,大大增强了战斗力,让你的APP 功能变得更加强大。

Android Studio 离线打包 阿里云 短视频 SDK 基础版

1.基础版: 只有录制和裁剪功能,

  1. 标准版:可以修改UI
  2. 专业版: 很复杂的功能
    可以参考,阿里云SDK说明
    阿里云短视频基础版

如何没有离线打包过的,可以参考,官方最新的AS 打包教程:
AS 最新离线打包教程


扫一扫下载安卓dome体验

里云的SDK包 QuSdk-RC.aar 复制到 libs/ 目录下,和 armeabi-v7a 文件夹复制到 libs/ 下里面是些os文件。

第二步:添加 阿里云 的依赖,在build.gradle ,文件 dependencies 里添加,

implementation(name: 'QuSdk-RC', ext: 'aar')  
    compile 'com.android.support:appcompat-v7:24.2.1'  
    compile 'com.android.support:design:24.2.1'  
    compile 'com.google.code.findbugs:jsr305:3.0.0'  
    compile 'com.github.bumptech.glide:glide:3.7.0'  
    compile 'pub.devrel:easypermissions:0.2.1'  
    compile 'com.squareup.okhttp3:okhttp:3.2.0'  
    compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar'  
    compile 'com.squareup.okio:okio:1.12.0'  
    compile 'com.google.code.gson:gson:2.8.0'

然后再在 在build.gradle 文件里和 dependencies 同级别 处添加

repositories {  
    flatDir {  
        dirs 'libs'  
    }  
}  

然后再在 在build.gradle 文件里android 处添加

 sourceSets.main {  
        jni.srcDirs = []  
        jniLibs.srcDir "libs"  
    }

然后在设置AndroidManifest.xml文件,声明使用权限(必须)

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  
<uses-permission android:name="android.permission.CAMERA" />  
<uses-permission android:name="android.permission.FLASHLIGHT" />  
<uses-permission android:name="android.permission.RECORD_VIDEO" />  
<uses-permission android:name="android.permission.RECORD_AUDIO" />  
<uses-permission android:name="android.permission.INTERNET" />  
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

第三步:以上权限,和SDK 的一些配置,已经配好了,下面进入写代码:
基础版的,代码很少,也简单,目前写两个java文件,一个用于初始化,别一个用于调用录制

要用视频录制,先初始化阿里云 短视频组件,
写了一个 :AliyunServer 类, 然在 dcloud_properties.xml ,services 服务项,添加一行,用于,应用打开时,就执行该文件,用于初始化阿里云 短视频组件

<service name="AliyunServer" value="com.Video.integrate.AliyunServer"/>

基础版,只需要添加这三行就可以。

package com.Video.integrate;  

import android.content.Context;  
import android.os.Bundle;  

import com.aliyun.common.httpfinal.QupaiHttpFinal;  

import io.dcloud.common.DHInterface.StandardFeature;  

/**  
 * Created by Administrator on 2018-06-20.  
 */  

public class AliyunServer extends StandardFeature  
{  
    public void onStart(Context pContext, Bundle pSavedInstanceState, String[] pRuntimeArgs) {  
        /**  
         * 如果需要在应用启动时进行初始化,可以继承这个方法,并在properties.xml文件的service节点添加扩展插件的注册即可触发onStart方法  
         * */  

        //当应用打开时,初始化,阿里SDK短视频 组件  
        System.loadLibrary("QuCore-ThirdParty");  
        System.loadLibrary("QuCore");  
        QupaiHttpFinal.getInstance().initOkHttpFinal();  
    }  
}  

第二步就是:AliyunVideo 类,用于调起录制页面

package com.Video.integrate;  

import android.app.Activity;  
import android.content.Intent;  
import android.os.Bundle;  
import android.view.Window;  

import com.aliyun.demo.recorder.AliyunVideoRecorder;  
import com.aliyun.struct.common.CropKey;  
import com.aliyun.struct.common.ScaleMode;  
import com.aliyun.struct.common.VideoQuality;  
import com.aliyun.struct.recorder.CameraType;  
import com.aliyun.struct.recorder.FlashType;  
import com.aliyun.struct.snap.AliyunSnapVideoParam;  

import org.json.JSONException;  
import org.json.JSONObject;  

public class AliyunVideo extends Activity  
{  
    private static final int REQUEST_CODE_RECORD_VIDEO= 1002;  
    private int resolutionMode,ratioMode,recordMode,beautyLevel,max,min,gop,minVideoDuration,maxVideoDuration,minCropDuration,frameRate,resulutionMode;  
    private boolean beautyStatus,needClip,needRecord;  
    private CameraType cameraType;  
    private FlashType flashType;  
    private VideoQuality videoQulity;  
    private ScaleMode cropMode;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);  
        Intent intent = this.getIntent();  
        String datajson= intent.getCharSequenceExtra("datajson").toString();  
        try {  
        JSONObject object=new JSONObject(datajson);  
        String _resolutionMode=object.getString("setResolutionMode");  
               resolutionMode=onRESOLUTION(_resolutionMode);  
        String _setRatioMode=object.getString("setRatioMode");  
             if(_setRatioMode.equals("1/1")){  
                ratioMode = AliyunSnapVideoParam.RATIO_MODE_1_1;  
            }else if(_setRatioMode.equals("3/4")){  
                ratioMode = AliyunSnapVideoParam.RATIO_MODE_3_4;  
            }else if(_setRatioMode.equals("9/16")){  
                ratioMode = AliyunSnapVideoParam.RATIO_MODE_9_16;  
            }  
        String _setRecordMode=object.getString("setRecordMode").trim().toLowerCase();  
            if(_setRecordMode.equals("auto")){  
                recordMode=AliyunSnapVideoParam.RECORD_MODE_AUTO;  
            }else if(_setRecordMode.equals("press")){  
                recordMode= AliyunSnapVideoParam.RECORD_MODE_PRESS;  
            }else if(_setRecordMode.equals("touch")){  
                recordMode= AliyunSnapVideoParam.RECORD_MODE_TOUCH;  
            }  
            beautyLevel=object.getInt("setBeautyLevel");  
            beautyStatus=object.getBoolean("setBeautyStatus");  
            String _cameraType=object.getString("setCameraType").trim().toLowerCase();  
            if(_cameraType.equals("front"))  
            {  
                cameraType=CameraType.FRONT;  
            //    Log.i("KPPPPPPPPFGGGGGGGGG", _cameraType);  
            } else{cameraType=CameraType.BACK;}  
            String _flashType=object.getString("setFlashType").trim().toLowerCase();  
            if(_flashType.equals("no")){  
                flashType=FlashType.ON;  
            }else if(_flashType.equals("off")){  
                flashType= FlashType.OFF;  
            }else if(_flashType.equals("auto")){  
                flashType= FlashType.AUTO;  
            }  
            needClip=object.getBoolean("setNeedClip");  
            max=object.getInt("setMaxDuration")*1000;  
            min=object.getInt("setMinDuration")*1000;  
            String _videoQuality=object.getString("setVideoQuality").trim().toLowerCase();  
            if(_videoQuality.equals("ld")){  
                videoQulity = VideoQuality.LD;  
            }else if(_videoQuality.equals("sd")){  
                videoQulity = VideoQuality.SD;  
            }else if(_videoQuality.equals("hd")){  
                videoQulity = VideoQuality.HD;  
            }else if(_videoQuality.equals("ssd")){  
                videoQulity = VideoQuality.SSD;  
            }  
            gop=object.getInt("setGop");  
            minVideoDuration=object.getInt("setMinVideoDuration")*1000;  
            maxVideoDuration=object.getInt("setMaxVideoDuration")*1000;  
            minCropDuration=object.getInt("setMinCropDuration")*1000;  
            frameRate=object.getInt("setFrameRate");  
            needRecord=object.getBoolean("setNeedRecord");  
            String _resulutionMode=object.getString("setResulutionMode");  
            resulutionMode=onRESOLUTION(_resulutionMode);  
            String _cropMode=object.getString("setCropMode").trim().toLowerCase();  
            cropMode=(_cropMode.equals("cpu")?ScaleMode.PS:ScaleMode.LB);  
        } catch (JSONException e){  
            e.printStackTrace();  
        }  

        AliyunSnapVideoParam recordParam=new AliyunSnapVideoParam.Builder()  
                .setResolutionMode(resolutionMode) //录制 设置录制分辨率,目前支持360p,480p,540p,720p  
                .setRatioMode(ratioMode)  //录制 设置视频比例,目前支持1:1,3:4,9:16  
                .setRecordMode(recordMode) //录制 设置录制模式,目前支持按录,点录和混合模式  
                //  .setFilterList(eff_dirs)  //录制 设置滤镜地址列表,具体滤镜接口接收的是一个滤镜数组  
                .setBeautyLevel(beautyLevel)   //录制 设置美颜度  
                .setBeautyStatus(beautyStatus) //录制 设置美颜开关  
                .setCameraType(cameraType) //录制 设置前后置摄像头  
                .setFlashType(flashType) //录制 设置闪光灯模式  
                .setNeedClip(needClip) //录制 设置是否需要支持片段录制  
                .setMaxDuration(max) //录制 设置最大录制时长 单位毫秒  
                .setMinDuration(min) //录制 设置最小录制时长 单位毫秒  
                .setVideoQuality(videoQulity) //录制设置视频质量  
                .setGop(gop) //设置关键帧间隔  
                //   .setVideoBitrate(2000) //录制设置视频码率,如果不设置则使用视频质量videoQulity参数计算出码率  
                .setMinVideoDuration(minVideoDuration) //裁剪 设置过滤的视频最小长度 单位毫秒  
                .setMaxVideoDuration(maxVideoDuration) //裁剪 设置过滤的视频最大长度 单位毫秒  
                .setMinCropDuration(minCropDuration) //裁剪 设置视频最小裁剪时间 单位毫秒  
                .setFrameRate(frameRate) //裁剪 设置帧率  
                .setNeedRecord(needRecord)//设置是否需要开放录制入口  
                .setResulutionMode(resulutionMode) //设置分辨率,目前支持360p,480p,540p,720p  
                .setCropMode(cropMode) //设置裁剪方式,是否使用gpu进行裁剪,不设置则默认使用cpu来裁剪  
                .setSortMode(AliyunSnapVideoParam.SORT_MODE_VIDEO) //设置导入相册过滤选择视频  
                .build();  
          AliyunVideoRecorder.startRecordForResult(this, REQUEST_CODE_RECORD_VIDEO, recordParam);  
    }  

    //分辨率  
    public int onRESOLUTION(String name)  
    {  
        name=name.trim().toLowerCase();  
        Integer num=0;  
        if(name.equals("360p"))  
        {    num= AliyunSnapVideoParam.RESOLUTION_360P;  
        }else if(name.equals("480p")){  
            num= AliyunSnapVideoParam.RESOLUTION_480P;  
        }else if(name.equals("540p")){  
            num= AliyunSnapVideoParam.RESOLUTION_540P;  
        }else if(name.equals("720p"))  
        {  
            num= AliyunSnapVideoParam.RESOLUTION_720P;  
        }  
        return num;  
    }  

    protected void onActivityResult(int requestCode, int resultCode, Intent data)  
    {  
        Intent intent=new Intent();  
        if(requestCode ==REQUEST_CODE_RECORD_VIDEO)  
        {  
            if(resultCode == Activity.RESULT_OK && data!= null)  
            {  
                int type = data.getIntExtra(AliyunVideoRecorder.RESULT_TYPE,0);  
                if(type ==  AliyunVideoRecorder.RESULT_TYPE_CROP) //截取视频  
                {  
                    String path = data.getStringExtra(CropKey.RESULT_KEY_CROP_PATH);  
                    intent.putExtra("resultCode","000000");  
                    intent.putExtra("type","CROP");  
                    intent.putExtra("path",path);  
                  //  intent.putExtra("time",data.getLongExtra(CropKey.RESULT_KEY_DURATION,0));  
                }else if(type ==  AliyunVideoRecorder.RESULT_TYPE_RECORD) //录制视频  
                {  
                    String path = data.getStringExtra(AliyunVideoRecorder.OUTPUT_PATH);  
                    intent.putExtra("resultCode","000000");  
                    intent.putExtra("type","RECORD");  
                    intent.putExtra("path",path);  
                  //  intent.putExtra("time",data.getLongExtra(AliyunVideoRecorder.R,0));  
                }  
            }else if(resultCode == Activity.RESULT_CANCELED)  
            {  
                intent.putExtra("resultCode","-1");  
            }  
        }  
        else {intent.putExtra("resultCode","-2");}  
        setResult(RESULT_OK,intent);  
        this.finish();  
    }  

}

然后在html 页面 用JS通过 Native.js,调用原生类 ,写了一个,AliyunVideo.js 插件:

//实例化插件  
        var   vide=new AliyunVideo(  
                {  
         setResolutionMode:"720p", //录制 设置录制分辨率,目前支持360p,480p,540p,720p  
         setRatioMode:"1/1", //录制 设置视频比例,目前支持1/1 ,3/4, 9/16  
         setRecordMode:"AUTO", //录制 设置录制模式,目前支持按录:PRESS,点录:TOUCH和混合模式:AUTO  
         setBeautyLevel:60, //录制 设置美颜度,1-100,比率  
         setBeautyStatus:true, //录制 设置美颜开关  
         setCameraType:"BACK",  //录制 设置前后置摄像头, 后:BACK ,前:FRONT  
         setFlashType:"OFF",  //录制 设置闪光灯模式,开:NO, 关:OFF, 自动:AUTO  
         setNeedClip:true, //录制 设置是否需要支持片段录制  
         setMaxDuration:15, //录制 设置最大录制时长 单位秒  
         setMinDuration:2, //录制 设置最小录制时长 单位秒  
         setVideoQuality:"HD", //录制设置视频质量 4个级别, 低:LD ,中:SD ,高:HD ,极高:SSD  
         setGop:125, //设置关键帧间隔,建议:1-300之间  
         setMinVideoDuration:5, //裁剪 设置过滤的视频最小长度 单位秒  
         setMaxVideoDuration:15, //裁剪 设置过滤的视频最大长度 单位秒  
         setMinCropDuration:2,  //裁剪 设置视频最小裁剪时间 单位毫秒  
         setFrameRate:25, //裁剪 设置帧率  
         setNeedRecord:false, //设置是否需要开放录制入口,即选择视频的页面,多出一个录制按钮  
         setResulutionMode:"540p", //设置裁剪分辨率,目前支持360p,480p,540p,720p  
         setCropMode:"cpu" //设置裁剪方式,是否使用gpu进行裁剪,不设置则默认使用cpu来裁剪  
                });

// js 打开录制视频页面

              vide.open(function(e)  
                 {  
                       if(e.code=="000000")  
                       {  
                                            //录制视频或裁剪视频,成功后,返回视频一个地址  
                            mui.toast("视频地址:"+e.path);  
                       }  
                       else if(e.code=="-1")  
                       { //用户取消行为  
                          mui.toast("用户已取消");  
                       }  
                 });

下面是AS工程包,因官方上传限制, 不包含阿里云的SDK, 另外下载

继续阅读 »

离线打包一些第三方的SDK, 犹如一名战士穿上铠甲,大大增强了战斗力,让你的APP 功能变得更加强大。

Android Studio 离线打包 阿里云 短视频 SDK 基础版

1.基础版: 只有录制和裁剪功能,

  1. 标准版:可以修改UI
  2. 专业版: 很复杂的功能
    可以参考,阿里云SDK说明
    阿里云短视频基础版

如何没有离线打包过的,可以参考,官方最新的AS 打包教程:
AS 最新离线打包教程


扫一扫下载安卓dome体验

里云的SDK包 QuSdk-RC.aar 复制到 libs/ 目录下,和 armeabi-v7a 文件夹复制到 libs/ 下里面是些os文件。

第二步:添加 阿里云 的依赖,在build.gradle ,文件 dependencies 里添加,

implementation(name: 'QuSdk-RC', ext: 'aar')  
    compile 'com.android.support:appcompat-v7:24.2.1'  
    compile 'com.android.support:design:24.2.1'  
    compile 'com.google.code.findbugs:jsr305:3.0.0'  
    compile 'com.github.bumptech.glide:glide:3.7.0'  
    compile 'pub.devrel:easypermissions:0.2.1'  
    compile 'com.squareup.okhttp3:okhttp:3.2.0'  
    compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar'  
    compile 'com.squareup.okio:okio:1.12.0'  
    compile 'com.google.code.gson:gson:2.8.0'

然后再在 在build.gradle 文件里和 dependencies 同级别 处添加

repositories {  
    flatDir {  
        dirs 'libs'  
    }  
}  

然后再在 在build.gradle 文件里android 处添加

 sourceSets.main {  
        jni.srcDirs = []  
        jniLibs.srcDir "libs"  
    }

然后在设置AndroidManifest.xml文件,声明使用权限(必须)

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />  
<uses-permission android:name="android.permission.CAMERA" />  
<uses-permission android:name="android.permission.FLASHLIGHT" />  
<uses-permission android:name="android.permission.RECORD_VIDEO" />  
<uses-permission android:name="android.permission.RECORD_AUDIO" />  
<uses-permission android:name="android.permission.INTERNET" />  
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

第三步:以上权限,和SDK 的一些配置,已经配好了,下面进入写代码:
基础版的,代码很少,也简单,目前写两个java文件,一个用于初始化,别一个用于调用录制

要用视频录制,先初始化阿里云 短视频组件,
写了一个 :AliyunServer 类, 然在 dcloud_properties.xml ,services 服务项,添加一行,用于,应用打开时,就执行该文件,用于初始化阿里云 短视频组件

<service name="AliyunServer" value="com.Video.integrate.AliyunServer"/>

基础版,只需要添加这三行就可以。

package com.Video.integrate;  

import android.content.Context;  
import android.os.Bundle;  

import com.aliyun.common.httpfinal.QupaiHttpFinal;  

import io.dcloud.common.DHInterface.StandardFeature;  

/**  
 * Created by Administrator on 2018-06-20.  
 */  

public class AliyunServer extends StandardFeature  
{  
    public void onStart(Context pContext, Bundle pSavedInstanceState, String[] pRuntimeArgs) {  
        /**  
         * 如果需要在应用启动时进行初始化,可以继承这个方法,并在properties.xml文件的service节点添加扩展插件的注册即可触发onStart方法  
         * */  

        //当应用打开时,初始化,阿里SDK短视频 组件  
        System.loadLibrary("QuCore-ThirdParty");  
        System.loadLibrary("QuCore");  
        QupaiHttpFinal.getInstance().initOkHttpFinal();  
    }  
}  

第二步就是:AliyunVideo 类,用于调起录制页面

package com.Video.integrate;  

import android.app.Activity;  
import android.content.Intent;  
import android.os.Bundle;  
import android.view.Window;  

import com.aliyun.demo.recorder.AliyunVideoRecorder;  
import com.aliyun.struct.common.CropKey;  
import com.aliyun.struct.common.ScaleMode;  
import com.aliyun.struct.common.VideoQuality;  
import com.aliyun.struct.recorder.CameraType;  
import com.aliyun.struct.recorder.FlashType;  
import com.aliyun.struct.snap.AliyunSnapVideoParam;  

import org.json.JSONException;  
import org.json.JSONObject;  

public class AliyunVideo extends Activity  
{  
    private static final int REQUEST_CODE_RECORD_VIDEO= 1002;  
    private int resolutionMode,ratioMode,recordMode,beautyLevel,max,min,gop,minVideoDuration,maxVideoDuration,minCropDuration,frameRate,resulutionMode;  
    private boolean beautyStatus,needClip,needRecord;  
    private CameraType cameraType;  
    private FlashType flashType;  
    private VideoQuality videoQulity;  
    private ScaleMode cropMode;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);  
        Intent intent = this.getIntent();  
        String datajson= intent.getCharSequenceExtra("datajson").toString();  
        try {  
        JSONObject object=new JSONObject(datajson);  
        String _resolutionMode=object.getString("setResolutionMode");  
               resolutionMode=onRESOLUTION(_resolutionMode);  
        String _setRatioMode=object.getString("setRatioMode");  
             if(_setRatioMode.equals("1/1")){  
                ratioMode = AliyunSnapVideoParam.RATIO_MODE_1_1;  
            }else if(_setRatioMode.equals("3/4")){  
                ratioMode = AliyunSnapVideoParam.RATIO_MODE_3_4;  
            }else if(_setRatioMode.equals("9/16")){  
                ratioMode = AliyunSnapVideoParam.RATIO_MODE_9_16;  
            }  
        String _setRecordMode=object.getString("setRecordMode").trim().toLowerCase();  
            if(_setRecordMode.equals("auto")){  
                recordMode=AliyunSnapVideoParam.RECORD_MODE_AUTO;  
            }else if(_setRecordMode.equals("press")){  
                recordMode= AliyunSnapVideoParam.RECORD_MODE_PRESS;  
            }else if(_setRecordMode.equals("touch")){  
                recordMode= AliyunSnapVideoParam.RECORD_MODE_TOUCH;  
            }  
            beautyLevel=object.getInt("setBeautyLevel");  
            beautyStatus=object.getBoolean("setBeautyStatus");  
            String _cameraType=object.getString("setCameraType").trim().toLowerCase();  
            if(_cameraType.equals("front"))  
            {  
                cameraType=CameraType.FRONT;  
            //    Log.i("KPPPPPPPPFGGGGGGGGG", _cameraType);  
            } else{cameraType=CameraType.BACK;}  
            String _flashType=object.getString("setFlashType").trim().toLowerCase();  
            if(_flashType.equals("no")){  
                flashType=FlashType.ON;  
            }else if(_flashType.equals("off")){  
                flashType= FlashType.OFF;  
            }else if(_flashType.equals("auto")){  
                flashType= FlashType.AUTO;  
            }  
            needClip=object.getBoolean("setNeedClip");  
            max=object.getInt("setMaxDuration")*1000;  
            min=object.getInt("setMinDuration")*1000;  
            String _videoQuality=object.getString("setVideoQuality").trim().toLowerCase();  
            if(_videoQuality.equals("ld")){  
                videoQulity = VideoQuality.LD;  
            }else if(_videoQuality.equals("sd")){  
                videoQulity = VideoQuality.SD;  
            }else if(_videoQuality.equals("hd")){  
                videoQulity = VideoQuality.HD;  
            }else if(_videoQuality.equals("ssd")){  
                videoQulity = VideoQuality.SSD;  
            }  
            gop=object.getInt("setGop");  
            minVideoDuration=object.getInt("setMinVideoDuration")*1000;  
            maxVideoDuration=object.getInt("setMaxVideoDuration")*1000;  
            minCropDuration=object.getInt("setMinCropDuration")*1000;  
            frameRate=object.getInt("setFrameRate");  
            needRecord=object.getBoolean("setNeedRecord");  
            String _resulutionMode=object.getString("setResulutionMode");  
            resulutionMode=onRESOLUTION(_resulutionMode);  
            String _cropMode=object.getString("setCropMode").trim().toLowerCase();  
            cropMode=(_cropMode.equals("cpu")?ScaleMode.PS:ScaleMode.LB);  
        } catch (JSONException e){  
            e.printStackTrace();  
        }  

        AliyunSnapVideoParam recordParam=new AliyunSnapVideoParam.Builder()  
                .setResolutionMode(resolutionMode) //录制 设置录制分辨率,目前支持360p,480p,540p,720p  
                .setRatioMode(ratioMode)  //录制 设置视频比例,目前支持1:1,3:4,9:16  
                .setRecordMode(recordMode) //录制 设置录制模式,目前支持按录,点录和混合模式  
                //  .setFilterList(eff_dirs)  //录制 设置滤镜地址列表,具体滤镜接口接收的是一个滤镜数组  
                .setBeautyLevel(beautyLevel)   //录制 设置美颜度  
                .setBeautyStatus(beautyStatus) //录制 设置美颜开关  
                .setCameraType(cameraType) //录制 设置前后置摄像头  
                .setFlashType(flashType) //录制 设置闪光灯模式  
                .setNeedClip(needClip) //录制 设置是否需要支持片段录制  
                .setMaxDuration(max) //录制 设置最大录制时长 单位毫秒  
                .setMinDuration(min) //录制 设置最小录制时长 单位毫秒  
                .setVideoQuality(videoQulity) //录制设置视频质量  
                .setGop(gop) //设置关键帧间隔  
                //   .setVideoBitrate(2000) //录制设置视频码率,如果不设置则使用视频质量videoQulity参数计算出码率  
                .setMinVideoDuration(minVideoDuration) //裁剪 设置过滤的视频最小长度 单位毫秒  
                .setMaxVideoDuration(maxVideoDuration) //裁剪 设置过滤的视频最大长度 单位毫秒  
                .setMinCropDuration(minCropDuration) //裁剪 设置视频最小裁剪时间 单位毫秒  
                .setFrameRate(frameRate) //裁剪 设置帧率  
                .setNeedRecord(needRecord)//设置是否需要开放录制入口  
                .setResulutionMode(resulutionMode) //设置分辨率,目前支持360p,480p,540p,720p  
                .setCropMode(cropMode) //设置裁剪方式,是否使用gpu进行裁剪,不设置则默认使用cpu来裁剪  
                .setSortMode(AliyunSnapVideoParam.SORT_MODE_VIDEO) //设置导入相册过滤选择视频  
                .build();  
          AliyunVideoRecorder.startRecordForResult(this, REQUEST_CODE_RECORD_VIDEO, recordParam);  
    }  

    //分辨率  
    public int onRESOLUTION(String name)  
    {  
        name=name.trim().toLowerCase();  
        Integer num=0;  
        if(name.equals("360p"))  
        {    num= AliyunSnapVideoParam.RESOLUTION_360P;  
        }else if(name.equals("480p")){  
            num= AliyunSnapVideoParam.RESOLUTION_480P;  
        }else if(name.equals("540p")){  
            num= AliyunSnapVideoParam.RESOLUTION_540P;  
        }else if(name.equals("720p"))  
        {  
            num= AliyunSnapVideoParam.RESOLUTION_720P;  
        }  
        return num;  
    }  

    protected void onActivityResult(int requestCode, int resultCode, Intent data)  
    {  
        Intent intent=new Intent();  
        if(requestCode ==REQUEST_CODE_RECORD_VIDEO)  
        {  
            if(resultCode == Activity.RESULT_OK && data!= null)  
            {  
                int type = data.getIntExtra(AliyunVideoRecorder.RESULT_TYPE,0);  
                if(type ==  AliyunVideoRecorder.RESULT_TYPE_CROP) //截取视频  
                {  
                    String path = data.getStringExtra(CropKey.RESULT_KEY_CROP_PATH);  
                    intent.putExtra("resultCode","000000");  
                    intent.putExtra("type","CROP");  
                    intent.putExtra("path",path);  
                  //  intent.putExtra("time",data.getLongExtra(CropKey.RESULT_KEY_DURATION,0));  
                }else if(type ==  AliyunVideoRecorder.RESULT_TYPE_RECORD) //录制视频  
                {  
                    String path = data.getStringExtra(AliyunVideoRecorder.OUTPUT_PATH);  
                    intent.putExtra("resultCode","000000");  
                    intent.putExtra("type","RECORD");  
                    intent.putExtra("path",path);  
                  //  intent.putExtra("time",data.getLongExtra(AliyunVideoRecorder.R,0));  
                }  
            }else if(resultCode == Activity.RESULT_CANCELED)  
            {  
                intent.putExtra("resultCode","-1");  
            }  
        }  
        else {intent.putExtra("resultCode","-2");}  
        setResult(RESULT_OK,intent);  
        this.finish();  
    }  

}

然后在html 页面 用JS通过 Native.js,调用原生类 ,写了一个,AliyunVideo.js 插件:

//实例化插件  
        var   vide=new AliyunVideo(  
                {  
         setResolutionMode:"720p", //录制 设置录制分辨率,目前支持360p,480p,540p,720p  
         setRatioMode:"1/1", //录制 设置视频比例,目前支持1/1 ,3/4, 9/16  
         setRecordMode:"AUTO", //录制 设置录制模式,目前支持按录:PRESS,点录:TOUCH和混合模式:AUTO  
         setBeautyLevel:60, //录制 设置美颜度,1-100,比率  
         setBeautyStatus:true, //录制 设置美颜开关  
         setCameraType:"BACK",  //录制 设置前后置摄像头, 后:BACK ,前:FRONT  
         setFlashType:"OFF",  //录制 设置闪光灯模式,开:NO, 关:OFF, 自动:AUTO  
         setNeedClip:true, //录制 设置是否需要支持片段录制  
         setMaxDuration:15, //录制 设置最大录制时长 单位秒  
         setMinDuration:2, //录制 设置最小录制时长 单位秒  
         setVideoQuality:"HD", //录制设置视频质量 4个级别, 低:LD ,中:SD ,高:HD ,极高:SSD  
         setGop:125, //设置关键帧间隔,建议:1-300之间  
         setMinVideoDuration:5, //裁剪 设置过滤的视频最小长度 单位秒  
         setMaxVideoDuration:15, //裁剪 设置过滤的视频最大长度 单位秒  
         setMinCropDuration:2,  //裁剪 设置视频最小裁剪时间 单位毫秒  
         setFrameRate:25, //裁剪 设置帧率  
         setNeedRecord:false, //设置是否需要开放录制入口,即选择视频的页面,多出一个录制按钮  
         setResulutionMode:"540p", //设置裁剪分辨率,目前支持360p,480p,540p,720p  
         setCropMode:"cpu" //设置裁剪方式,是否使用gpu进行裁剪,不设置则默认使用cpu来裁剪  
                });

// js 打开录制视频页面

              vide.open(function(e)  
                 {  
                       if(e.code=="000000")  
                       {  
                                            //录制视频或裁剪视频,成功后,返回视频一个地址  
                            mui.toast("视频地址:"+e.path);  
                       }  
                       else if(e.code=="-1")  
                       { //用户取消行为  
                          mui.toast("用户已取消");  
                       }  
                 });

下面是AS工程包,因官方上传限制, 不包含阿里云的SDK, 另外下载

收起阅读 »