云开发 Serverless 从入门到实战

Serverless

指构建和运行不需要服务器管理的应用程序的概念。
Serverless 是 FaaS 和 BaaS 的结合。Serverless = FaaS + BaaS。

FaaS(Function as a Service) 就是一些运行函数的平台,比如阿里云的函数计算、AWS 的 Lambda 等。
BaaS(Backend as a Service)则是一些后端云服务,比如云数据库、对象存储、消息队列等。利用 BaaS,可以极大简化我们的应用开发难度。

Serverless 的主要特点有:

  • 事件驱动
  • 函数在 FaaS 平台中,需要通过一系列的事件来驱动函数执行。
  • 无状态
  • 因为每次函数执行,可能使用的都是不同的容器,无法进行内存或数据共享。如果要共享数据,则只能通过第三方服务,比如 Redis 等。
  • 无运维
  • 使用 Serverless 我们不需要关心服务器,不需要关心运维。这也是 Serverless 思想的核心。
  • 低成本
  • 使用 Serverless 成本很低,因为我们只需要为每次函数的运行付费。函数不运行,则不花钱,也不会浪费服务器资源

前端工程师基于 Serverless 去写后端,最好也需要具备一定的后端知识。涉及复杂的后端系统或者 Serverless 不适用的场景,还是需要后端开发,后端变得更靠后了。

Serverless 开发最佳实践

将业务逻辑和函数依赖的 FaaS(如函数计算) 和 BaaS (如云数据库)分离。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Users {
constructor(db, mailer) {
this.db = db;
this.mailer = mailer;
}
save(email, callback) {
const user = {
email: email,
created_at: Date.now()
}
this.db.saveUser(user, function (err) {
if (err) {
callback(err);
} else {
this.mailer.sendWelcomeEmail(email);
callback();
}
});
}
}
module.exports = Users;

const db = require('db').connect();
const mailer = require('mailer');
const Users = require('users');
let users = new Users(db, mailer);
module.exports.saveUser = (event, context, callback) => {
users.save(event.email, callback);
};

将业务逻辑全都放在了 Users 这个类里面,Users 不依赖任何外部服务。

函数的性能

当驱动函数执行的事件到来的时候,首先需要下载代码,然后启动一个容器,在容器里面再启动一个运行环境,最后才是执行代码。前几步统称为冷启动(Cold Start)。传统的应用没有冷启动的过程。

当第一次请求(驱动函数执行的事件)来临,成功启动运行环境并执行函数之后,运行环境会保留一段时间,以便用于下一次函数执行。这样就能减少冷启动的次数,从而缩短函数运行时间。当请求达到一个运行环境的限制时,FaaS 平台会自动扩展下一个运行环境。

执行上下文重用

1
2
3
4
5
6
const mysql = require('mysql');
// 初始化数据库连接 const connection = mysql.createConnection({ /* ... */ });
connection.connect();
module.exports.saveUser = (event, context, callback) => {
connection.query('...');
};

这样就只有第一次运行环境启动的时候,才会初始化数据库连接。后续请求来临、执行函数的时候,就可以直接利用执行上下文中的 connection,从而提高后续高函数的性能。
大部分情况下,通过牺牲一个请求的性能,换取大部分请求的性能,是完全可以够接受的。

给函数预热

通过主动调用函数的方式,隔一段时间就冷启动一个运行环境,这样就能使得其他正常的请求都是热启动,从而避免冷启动时间对函数性能的影响。

需要注意:

  • 不要过于频繁调用函数,至少频率要大于 5 分钟
  • 直接调用函数,而不是通过网关等间接调用
  • 创建专门处理这种预热调用的函数,而不是正常业务函数

如果你的业务允许“牺牲第一个请求的性能换取大部分性能”,那也完全不必使用该方案,

阅读更多

uni-app 从入门到实践开发

uni-app

uni-app背景介绍

当前跨平台开发存在的3个问题
1、多端泛滥
2、体验不好
3、生态不丰富

uni-app 产品特征

1、跨平台更多 —— 条件编译:优雅的在一个项目里调用不同平台的特色功能!
2、运行体验更好 —— 组件、api与微信小程序一致,兼容 weex 原生渲染
3、通用技术栈,学习成本更低 —— vue 的语法、微信小程序的api、内嵌 mpvue
4、开放生态,组件更丰富 —— 支持通过 npm 安装第三方包、支持微信小程序自定义组件及 SDK、兼容 mpvue 组件及项目、App 端支持和原生混合编码、DCloud 将发布插件市场

功能框架

功能框架

uni-app 规范

页面文件遵循 Vue 单文件组件(SFC)规范
组件标签靠近小程序规范
接口能力(JS API)靠近微信小程序规范
数据绑定及事件处理同 Vue.js 规范
为兼容多端运行,建议使用 flex 布局进行开发

条件编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<view class="content">
<!-- #ifdef MP-WEIXIN -->
<view class="">
只会编译到小程序
</view>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view class="">
只会编译到 APP
</view>
<!-- #endif -->
</view>
</template>

生命周期

应用生命周期

页面生命周期

组件生命周期

组件

name

配置

pages.json

globalStyle

pages

API

快速创建项目

通过 HBuilderX 创建项目

通过vue-cli命令行 创建项目

1
2
3
// 安装 vue cli
npm install -g @vue/cli
vue create -p dcloudio/uni-preset-vue my-project

native.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//  安卓 拨打电话
function call(){
// 导入Activity、Intent类
var Intent = plus.android.importClass("android.content.Intent");
var Uri = plus.android.importClass("android.net.Uri");
// 获取主Activity对象的实例
var main = plus.android.runtimeMainActivity();
// 创建Intent
var uri = Uri.parse("tel:10010"); // 这里可修改电话号码
var call = new Intent("android.intent.action.CALL",uri);
// 调用startActivity方法拨打电话
main.startActivity( call );
// ...
}

uni-app 项目

目录结构

单文件

vue.js

文件导入

尺寸单位

rpx

代码块提示

HBuilderX 快捷键

项目发行

项目配置 页面配置

pages style app-plus

微信小程序 配置
condition:{
}

navigator 跳转

组件、组件生命周期

组件传值 props\emit、uni.$on、uni.$emit

uni-ui 组件库的引入

uni-app 规范

条件编译

App 端的 nvue 开发

HTML5+

组件、自定义组件、基础组件、生命周期、路由、API、语法、布局样式

Hbuiderx

vuecli方式

微信开放平台 unionid

分享

交互反馈

redis 根据用户信息生成 随机 key 登录根基这个生成的随机键来判断

(根据用户信息+上次登录的时间)-临时想法

uniapp 一键登录

e.currentTarget.id

e.target.id

获取系统信息

设置导航条

下拉刷新 onpullDownRefresh

上拉加载 onReachBottom

登录 openid unionid多端一致 微信开发平台

全局变量

节点信息

socket 的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import io from './common/weapp.socket.io.js'

Vue.prototype.socket = io('http://192.168.1.3:8082')


methods:{
// 发送讯息
send: function(){
if(this.cont.length>0){
this.arr.push(this.cont);
let aa = this.cont
this.socket.emit('message','aa')
}
}
// 接受广播讯息
getmsg: function(){
this.socket.on('gbmsg',data=>{
this.arr.push(data);
})
}
}

uni-app 去掉 App、h5 端的导航栏

pages.json

1
2
3
4
5
6
7
8
9
"globalStyle": {
"navigationBarTextStyle": "white",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#007AFF",
"backgroundColor": "#FFFFFF",
"h5": {
"titleNView": false
}
}

全局样式引入

vue

1
2
3
4
// App.vue 
<style>
@import url('/common/free.css')
</style>

引入图标库

1
2
3
4
5
/* icon.css */
@font-face{
font-family: "iconfont";
src: url('data:base64') format('woff2');
}
1
2
3
4
5
6
// App.vue
<style>
/* #ifndef APP-PLUS-NVUE */
@import url('/common/icon.css')
/* endif */
</style>

nvue

1
2
3
4
5
6
7
8
9
10
11
// 只支持 unicode
// App.vue
<script>
onLaunch: function(){
const domModule = weex.requireModule('dom')
domModule.addRule('fontFace', {
'fontFamily': "iconfont",
'src': "url('http://at.alicdn.com/t/font_1469606063_76593.ttf')"
});
}
</script>

midButton 中间凸起按钮设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
{
"pages": [{
"path": "pages/component/index",
"style": {
"navigationBarTitleText": "组件"
}
}, {
"path": "pages/API/index",
"style": {
"navigationBarTitleText": "接口"
}
}, {
"path": "pages/component/view/index",
"style": {
"navigationBarTitleText": "view"
}
}],
"condition": { //模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项)
"list": [{
"name": "test", //模式名称
"path": "pages/component/view/index" //启动页面,必选
}]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "演示",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8",
"usingComponents":{
"collapse-tree-item":"/components/collapse-tree-item"
},
"renderingMode": "seperated", // 仅微信小程序,webrtc 无法正常时尝试强制关闭同层渲染
"pageOrientation": "portrait", //横屏配置,全局屏幕旋转设置(仅 APP/微信/QQ小程序),支持 auto / portrait / landscape
"rpxCalcMaxDeviceWidth": 960,
"rpxCalcBaseDeviceWidth": 375,
"rpxCalcIncludeWidth": 750
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"height": "50px",
"fontSize": "10px",
"iconWidth": "24px",
"spacing": "3px",
"list": [{
"pagePath": "pages/component/index",
"iconPath": "static/image/icon_component.png",
"selectedIconPath": "static/image/icon_component_HL.png",
"text": "组件"
}, {
"pagePath": "pages/API/index",
"iconPath": "static/image/icon_API.png",
"selectedIconPath": "static/image/icon_API_HL.png",
"text": "接口"
}],
"midButton": {
"width": "80px",
"height": "50px",
"text": "文字",
"iconPath": "static/image/midButton_iconPath.png",
"iconWidth": "24px",
"backgroundImage": "static/image/midButton_backgroundImage.png"
}
},
"easycom": {
"autoscan": true, //是否自动扫描组件
"custom": {//自定义扫描规则
"^uni-(.*)": "@/components/uni-$1.vue"
}
},
"topWindow": {
"path": "responsive/top-window.vue",
"style": {
"height": "44px"
}
},
"leftWindow": {
"path": "responsive/left-window.vue",
"style": {
"width": "300px"
}
},
"rightWindow": {
"path": "responsive/right-window.vue",
"style": {
"width": "300px"
},
"matchMedia": {
"minWidth": 768
}
}
}
1
2
3
4
5
6
7
8
// 只支持 unicode
// App.vue
<script>
onLaunch: function(){
uni.onTabBarMidButtonTap(()=>{
})
}
</script>

业务

刷礼物

list
App nvue 专用组件
app端nvue专用组件。在app-nvue下,如果是长列表,使用list组件的性能高于使用view或scroll-view的滚动。原因在于list在不可见部分的渲染资源回收有特殊的优化处理。

如果需要跨端,建议使用 uni-ui 的 uni-list组件,它会自动处理webview渲染和原生渲染的情况,在app-nvue下使用list组件,而在其他平台则使用页面滚动。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// live.nvue
<template>
<f-gift ref="gift"></f-gift>
</template>
<script>
mounted(){
setInterval(()=>{
this.$refs.gift.send({
username: '发送人',
avatar: "",
gift_name: '蛋糕',
gift_image: '/static/gift/3.png',
num: 1
})
})
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//  f-gift.vue 礼物组件
<template>
<list style="width:520rpx;height:500rpx;" :show-scrollbar="false" :bounce="false">
<!-- 注意事项: 不能使用 index 作为 key 的唯一标识 -->
<cell class="flex align-center px-3" v-for="(item, index) in dataList" :key="item.id" insert-animation="default" delete-animation="default">
<view style="width: 325rpx;">
</view>
</cell>
</list>
</template>

<script>
const domModule = weex.requireModule('dom')

export default {
data () {
return {
gifts: [{}]
}
},
method:{
// 送礼物
send(gift){
this.gifts.push(gift)
this.toBottom();
this.autoHide();
}
// 置于底部
toBottom(){
this.$nextTick(() => {
let index = this.gifts.length -1
let ref = 'item' + index
if(this.$refs[ref]){
dom.scrollToElement(this.$refs[ref][0],{})
}
})
},
// 自动消失
autoHide(){
if(this.gifts.length){
let timer = setTimeout(()=>{
this.gifts.splice(0,1);
},5000)
}
}
}
}
</script>

弹幕

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<view>
<scroll-view scroll-y="true" scroll-with-animation :scroll-inio-view="scrollInToView">
<view :id="'danmu'+item.id" >
</view>
</scrioll-view>
</view>
</template>
<script>
methods: {
toBottom(){
let len = this.list.length;
if(len > 0 && this.list[len-1]){
this.scrollInToView = 'danmu' + this.list[len - 1].id
}
}
}
</script>

UI 框架

uView:uView是uni-app生态专用的UI框架,uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码, 可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台(引言自uni-app网)
ThorUI:简约而不简单一直是ThorUI的追求。ThorUI目前有微信小程序原生版本uni-app版本,后续会扩展到其他原生版本,扩大生态。 除了组件库ThorUI还会陆续发布一些常用模板,使开发更加高效。

目前组件与模板默认支持App端(IOS和Android)、H5、微信小程序、QQ小程序。

colorui:鲜亮的高饱和色彩,专注视觉的小程序组件库

报错

微信小程序

  • forceUpdate 错误
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SystemError (appServiceSDKScriptError)
Cannot read property 'forceUpdate' of undefined
TypeError: Cannot read property 'forceUpdate' of undefined
at http://127.0.0.1:28307/appservice/__dev__/WAService.js:2:1415111
at http://127.0.0.1:28307/appservice/__dev__/WAService.js:2:633507
at o (http://127.0.0.1:28307/appservice/__dev__/asdebug.js:1:3197)
at e.exports.<anonymous> (http://127.0.0.1:28307/appservice/__dev__/asdebug.js:1:3577)
at http://127.0.0.1:28307/appservice/__dev__/asdebug.js:1:1844
at Array.forEach (<anonymous>)
at WebSocket._ws.onmessage (http://127.0.0.1:28307/appservice/__dev__/asdebug.js:1:1826)
console.error @ VM38:1
errorReport @ VM45 WAService.js:2
(anonymous) @ VM45 WAService.js:2
(anonymous) @ VM45 WAService.js:2
o @ VM42 asdebug.js:1
(anonymous) @ VM42 asdebug.js:1
(anonymous) @ VM42 asdebug.js:1
_ws.onmessage @ VM42 asdebug.js:1

配置微信小程序 AppID

  • sitemap.json 错误

sitemap.json Error: 未找到入口 sitemap49.json 文件,或者文件读取失败,请检查后重新编译。

根目录下创建 sitemap.json 并配置

uni-app 图表
  • H5端流行的echart报表因为涉及大量dom操作,无法跨端使用,而wx-chart在跨端和更新方面都不足,如果要做小程序,推荐使用全端可用的uChart
  •  如只考虑H5端,也可以继续使用 echart、f2等常规web图表。
  •  如不考虑小程序,那么App端和H5,还可以通过renderjs 技术来使用 echart、f2等web图表,功能性能比uchart更好。什么是renderjs基于renderjs使用echart的示例

不开发APP,可以不使用nvue

插件

插件大赛2020评奖结果揭晓,这些优秀的插件你都用起来了吗?

极光认证官方SDK

uCharts高性能跨全端图表

uParse修复版-html富文本加载

APP-引导页+官方示例

封装的request网络请求

开源项目

Uni-App

awesome-uni-app

来客推电商 / 小程序商城+APP+SaaS+前后代码开源


相关资料
[视频]uni-app跨平台框架官方教程
[视频]uni-app实战直播app全栈开发,uni-app实战视频教程

[视频]uni-App从入门到实战
[视频]uni-app实战商城类app和小程序

[视频]uni-app 快速入门 从零开始实现新闻资讯类跨端应用
[视频]uni-app基础+进阶+案例
[视频]uni-app零基础入门到项目实战

uni-app 零基础到实战课程

2020uniApp视频全套资料配源码【千锋Web前端】
uniapp 打造美团外卖微信小程序,uni-app,vue 中高级实战课程
ThinkPHP6+uniapp实战开发【简书app】
uni-app 跨平台 App 终极解决方案
uni-app视频教程合集|UniApp实战教程

小程序开发:用原生还是选框架(wepy/mpvue/taro/uni-app)– 第1季
创建、运行、发布uni-app
uni-app 全局变量的几种实现方式
uni-app 中保持用户登录状态
uni-app去掉h5端的导航栏
uni-app中过滤器的使用
uniapp获取微信手机号码
uni-app H5跨域问题解决方案(CORS、Cross-Origin)
直播业务指南
历时六个月月完全由UNI做推流APP的经历分享

跨平台前端框架uni-app学习
Native.js示例汇总
dcloud 社区问答

SystemError (appServiceSDKScriptError)
高效开发技巧
开发规范

uni-app官方教程学习手记
uni-app—从安装到卸载
wepy踩坑 sitemap.json Error: 未找到入口 sitemap49.json 文件,或者文件读取失败,请检查后重新编译。
解决uni-app开发环境中H5端跨域问题

uni-app 全局变量的几种实现方式

uni-app 启动界面(splash)参数配置说明 | 启动慢的原因(https://ask.dcloud.net.cn/article/35021)

HBuilder X运行小程序时,打开了微信开发者工具,但微信开发者工具未运行项目但又没有错误提示

uni-app 小程序系列教程

uni-app官网

uni-app 资源在线升级/热更新

uni-app 整包升级/更新方案

关于 uni-app
白话uni-app
vue
vue和微信小程序的区别、比较
uni-ui
H5 端路由配置
网络请求封装拦截等可参考插件市场
从App端跳转到微信小程序方式
uni-app导航栏文档和注意事项
导航栏开发指南
导航栏演示示例
uni-app大法好 ,nvue 从入坑到放弃
uni-app小程序手把手项目实战

uni-app网络请求封装
uni-app 请求封装

http://www.hcoder.net/tutorials/info/id/1335

Native.js示例汇总

直播从入门到实践开发

大前端技能

ES6、react、vue、webpack、angluar

服务类

node.js
express.js
koa.js

3d 数据图像

three.js

二维图像

d3.js
raphael.js
echart.js

视频

video.js
hls.js
flv.js

直播

直播原理

直播原理

视频格式

hls 对应的是 ts格式的视频,只有苹果浏览器支持
mp4、webm 偏点播 hls、flv偏直播

直播协议

HLS 协议 tm视频格式 延时
RTMP 协议 flv 视频格式 配置复杂
HTTP-FLV协议 flv 视频格式 低延时、

HLS协议

HLS协议

HLS协议

live playlist(动态列表)直播
event playlist(静态列表)
vod playlist(全量列表)点播

动态列表
静态列表
全量列表

ts 文件

延时跟 m318 文件跟切片有关系

RTMP 协议
RTMP 是 Real Time Messaging Protocol (实时消息传输协议)的首字母缩写。
该协议基于 TCP,是一个协议族,包括 RTMP 基本协议及 RTMPT/RTMPS/RTMPE 等多种变种。RTMP 是一种设计用来进行实时数据通信的网络协议,主要用来在 Flash、AIR 平台和支持 RTMP 协议的流媒体/交互服务器之间进行音视频和数据通信。主播客户端使用。flv视频格式。

采集端用 web 来做 协议是 webrtc。

RTMP 协议

HTTP-FLV协议

接合二者优点
flv 视频格式
建立长连接
建立 HTTP 协议

HTTP-FLV协议

1、可以在一定程度上避免防火墙的干扰(例如:有的机房只允许 80 端口通过)
2、可以很好的兼容 HTTP 302 跳转,做到灵活调度
3、可以使用 HTTPS 做加密通道
4、很好的支持移动端(android,ios)

video

属性和方法

贴图 poster
控制条 controls
自动播放 autoplay
循环播放 loop
预加载 preload
音量 volume
播放地址设置
静音 muted
播放时间设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!-- 控制条 无下载无全屏 -->
<video controls controlslist="nodownload nofullscreen"></video>
<!-- 贴图 -->
<video poster='./poster.jpg'></video>
<!-- 自动播放 -->
<video autoplay></video>
<!-- 静音 非静音状态下的视频是不允许自动播放的 -->
<video muted></video>
<!-- 循环播放 -->
<video loop></video>
<!-- 预加载 -->
<video preload></video>
<!-- 音量控制 -->
<video id="_volume"></video>
<script>
var v = document.getElementById('_volume')
v.volume = 0.5
</script>
<!-- 控制播放时间 -->
<script>
var v = document.getElementById('_volume')
v.currentTime = 60 //单位秒
</script>
<!-- 切换视频地址 -->
<script>
var v = document.getElementById('_volume')
v.src = './test-2.mp4' //单位秒
</script>
<!-- 备用地址 -->
<video width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.ogg" type="video/ogg">
您的浏览器不支持Video标签。
</video>
<script>
var v = document.getElementById('_volume')
setTimeout(function(){
console.log('src',v.currentSrc);
},1000)
</script>

事件

视频查找
时长变化
元数据加载
视频下载监听
可播放监听
播放监听
暂停监听
查找开始
查找结束
视频加载等待
视频结束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<video id="_volume"></video>
<script>
var v = document.getElementById('_volume');
console.log(v.duration);
// 视频开始加载
v.addEventListener('loadstart',function(e){
console.log('loadstart');
})

// 监听事长变化
v.addEventListener('durationchange',function(e){
console.log('loadstart');
// 查看视频时长
console.log(v.duration);
})

// 获取到视频的源数据
v.addEventListener('loadedmetadata',function(e){
console.log('loadedmetadata');
})

// 加载下一帧
v.addEventListener('loadeddata',function(e){
console.log('loadeddata');
})

// 正在下载
v.addEventListener('progress',function(e){
console.log('progress');
})

// 视频可以播放
v.addEventListener('canplay',function(e){
console.log('canplay');
})

// 视频可以流程播放了
v.addEventListener('canplaythrough',function(e){
console.log('canplaythrough');
})

// canplay、canplaythrough 之后允许播放
// 播放触发
v.addEventListener('play',function(e){
console.log('play');
})

// 暂停
v.addEventListener('pause',function(e){
console.log('pause');
})

// 监听播放位置改变
v.addEventListener('seeking',function(e){
console.log('seeking');
})

// seeking 结束
v.addEventListener('seeked',function(e){
console.log('seeked');
})

// waiting 等待 视频无法解码
v.addEventListener('waiting',function(e){
console.log('waiting');
})

// 当音频/视频在已因缓冲而暂停或停止后已就绪时
v.addEventListener('playing',function(e){
console.log('playing');
})

// 当目前的播放位置已更改时
v.addEventListener('timeupdate',function(e){
console.log('timeupdate');
})

// 返回音频/视频的播放是否已结束
v.addEventListener('ended',function(e){
console.log('ended');
})

// 返回表示音频/视频错误状态的 MediaError 对象
v.addEventListener('error',function(e){
console.log(v.error.code);
})
</script>

直播源的制作

方法一 nginx + ffmpeg

1、安装 nginx、ffmpeg
2、配置 nginx
3、准备视频
4、利用 ffmpeg 推流

安装 Nginx

Mac: brew install nginx-full –with-rtmp-module
windows:http://nginx.org/en/download.html

windows 下载如下
nginx/Windows-1.18.0 pgp

安装 ffmpeg

Mac:brew install ffmpeg
windows:https://ffmpeg.org/download.html
ffmpeg
下载 ffmpeg

ffmpeg 检查是否安装

命令行输入 ffmpeg

配置 nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /usr/local/var/www;
add_header Cache-Control no-cache;
}

rtmp {
server {

# rtmp 直播流配置
application rtmplive {
# 开启
live on;
# 最大连接数
max_connections 1024;
}

# hls 直播流配置
application hls {
# 开启
live on;
hls on;
# 文件存储地址
hls_path /usr/local/var/www/hls
hls_fragment 5s;
}
}
}

启动 nginx 的配置不报错,退出的时候报错,报错信息是以下内容
nginx: [emerg] unknown directive “rtmp” in D:\nginx-1.18.0/conf/nginx.conf:9
网上说用记事本打开会增加 utf8-bom 什么的格式导致,但是我下来了nginx-rtmp-module 中的测试例子仍报错。网上资料显示说下载自带 rtmp 模块的 nginx 版本 如 nginx 1.7.11.3 Gryphon。网上资料说下载 nginx 1.8.1版本然后下载 nginx-rtmp-module 启动命令 ./sbin/nginx -s reload,尝试了下,启动不了 ………… 问题搁置

推流

ffmpeg -re -i IPX-451.mp4 -vcodec libx264 -acodec aac -f flv rtmp://localhost:1935/rtmplive/rtm
ffmpeg -re -i IPX-451.mp4 -vcodec libx264 -acodec aac -f flv rtmp://localhost:1935/hls/stream

下载 vlc播放器
验证推流过程

方法二 集成服务

1、下载服务
2、安装服务
3、准备源视频
4、开启服务
5、利用 ffmpeg 推流

启动 server 下服务

open server

推流命令

ffmpeg -re -i IPX-451.mp4 -c copy -f flv rtmp://localhost:1935/live/movie

验证地址

RTMP:rtmp://localhost:1935/live/movie
FLV:http://127.0.0.1:7001/live/movie.flv
HLS:http://127.0.0.1:7002/live/movie.m3u8

H5 直播

video.js:自定义UI、快捷键、弹幕、播放 HLS
hls.js:HLS 类型的直播点播、小巧
flv.js:HTTP-FLV协议

全局安装 eslint

npm i eslint -g

配置
eslint –init


相关资料
[视频]H5与小程序直播开发视频教程

如何开发一款H5小程序直播

DPlayer:视频播放器
xgplayer:具有解析器的HTML5视频播放器,可节省流量
nginx-rtmp-module:基于NGINX的媒体流服务器
H5与小程序直播开发视频 源码:具有解析器的HTML5视频播放器,可节省流量

videojs 的插件和皮肤

超简单的FFmpeg安装方法
vue : 无法加载文件 C:\Users\XXX\AppData\Roaming\npm\vue.ps1,因为在此系统上禁止运行脚本
windows下nginx的rtmp配置加载问题 unknown directive “rtmp”
使用nginx-rtmp-module搭建RTMP直播服务器
关于HLS直播流HTML页面播放解决

HTML5视频直播及H5直播扫盲
大前端介绍与直播原理
前端中的直播
[使用flv.js做直播](https://github.com/gwuhaolin/blog/issues/3
web前端 html5 直播功能开发
使用flv.js快速搭建html5网页直播
html5-dash-hls-rtmp
关于flv.js 在ios端播放时候id兼容问题
直播中前端技术

Taro 从入门到实战

配置文件

更改端口号和域名:

config/index.js

1
2
h5: {
devServer:{ host: 'localhost', port: 8888},

更改 appid:
project.config.json(小程序独有的配置文件)

1
"appid": "touristappid",
阅读更多

多端统一开发解决方案

随着微信小程序的火爆,各家厂商纷纷推出自己的小程序,手机厂商也推出轻应用,这意味着开发者要面对不同平台都要开发一套,于是开发一套代码多平台运行成为构想,

Uniapp

使用 Vue 开发所有前端应用的框架,开发者编写一套代码,可发布到 iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台。

标签:Vue、大量开源项目

Apiclound

使用可视化工具快速构建应用程序,基于大数据与拖拽式产品工具自动关联项目组件,并帮助项目快速落地

标签:可视化工具、操作简单快捷

Mpvue

使用 Vue.js 开发小程序的前端框架。框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套 Vue.js 开发体验。

标签:Vue、小程序

Taro

Taro 是一套遵循 React 语法规范的 多端开发 解决方案。使用 Taro,只书写一套代码,再通过 Taro 的编译工具,将源代码分别编译出可以在不同终端(微信/百度/支付宝/字节跳动/QQ 小程序、快应用、H5、React-Native 等)运行的代码。

标签:React


以上是我对下列视频及文章的归纳和总结。
4款前端移动端开发框架

You need to set client_id and slot_id to show this AD unit. Please set it in _config.yml.