本文共 9247 字,大约阅读时间需要 30 分钟。
- open source HTML5 & Flash video player
作为一款高性能流媒体服务器的前端, 必不可少会用到流媒体播放器. 在播放器的选择上, 我们选中了功能强大并且开源的 video.js . 它可以用来播放 RTMP/HLS 直播流.
本篇介绍在 webpack 中集成 video.js 播放器组件, 我们将要完成一个 HLS 播放器
的小例子. 先来看一下效果图吧:
我们要开发的 HLS 播放器 需要用到 video.js 的一个官方插件:
尽管 video.js 官方文档中给出了 webpack 集成的说明(), 但是在实际开发过程中, 我还是和其他人一样遇到了很多坑() 最后, 算是将 video.js 集成好, 却发现插放 HLS 流, 不能切换到 Flash 模式. 最终, 我决定采用外部依赖的方式集成 video.js, 正好借此熟悉一下 webpack externals 的用法. 这里介绍的也就是 “外部依赖法”.
既是"外部依赖法", 那我们首先把外部依赖的 video.js 文件准备好. 在 src 目录下新建 externals 目录, 把事先下载好的 video-js-5.19.2 目录文件拷贝到这里.
修改 template.html 如下:
<%= htmlWebpackPlugin.options.title %>
修改 webpack.dll.config.js 如下:
const HtmlWebpackPlugin = require('html-webpack-plugin');const CleanWebpackPlugin = require('clean-webpack-plugin');const CopyWebpackPlugin = require('copy-webpack-plugin');const webpack = require('webpack');const path = require('path');function resolve(dir) { return path.resolve(__dirname, dir)}module.exports = { entry: { //提取共用组件, 打包成 vendor.js vendor: ['jquery', 'vue', 'vuex', 'babel-polyfill', 'font-awesome/css/font-awesome.css', 'admin-lte/bootstrap/css/bootstrap.css', 'admin-lte/dist/css/AdminLTE.css', 'admin-lte/dist/css/skins/_all-skins.css', 'admin-lte/bootstrap/js/bootstrap.js', 'admin-lte/dist/js/app.js'] }, output: { path: resolve('dll'), filename: 'js/[name].[chunkhash:8].js', library: '[name]_library' }, resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.common.js', 'jquery$': 'admin-lte/plugins/jQuery/jquery-2.2.3.min.js' } }, module: { rules: [{ test: /\.css$/, loader: 'style-loader!css-loader' }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader?limit=10000&name=images/[name].[hash:8].[ext]' }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader?limit=10000&name=fonts/[name].[hash:8].[ext]' }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader?limit=10000&name=media/[name].[hash:8].[ext]' }] }, plugins: [ new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', "window.jQuery": 'jquery', "window.$": 'jquery' }), new CleanWebpackPlugin(['dll']), new CopyWebpackPlugin([ { from: 'src/externals' } ]), new webpack.DllPlugin({ path: resolve("dll/[name]-manifest.json"), name: "[name]_library", context: __dirname }), new HtmlWebpackPlugin({ filename: 'template.html', title: '<%= htmlWebpackPlugin.options.title %>', inject: 'head', chunks: ['vendor'], template: './src/template.html', minify: { removeComments: true, collapseWhitespace: false } }) ]};
引入 CopyWebpackPlugin 将 externals 目录下的外部依赖文件拷贝到 dll 目录, 最终, 这些外部依赖文件将被拷贝到发布目录下
修改 webpack.config.js 如下:
const HtmlWebpackPlugin = require('html-webpack-plugin');const CleanWebpackPlugin = require('clean-webpack-plugin');const CopyWebpackPlugin = require('copy-webpack-plugin');const webpack = require('webpack');const path = require('path');require("babel-polyfill");function resolve(dir) { return path.resolve(__dirname, dir)}module.exports = { //定义页面的入口, 因为js中将要使用es6语法, 所以这里需要依赖 babel 垫片 entry: { index: ['babel-polyfill', './src/index.js'], player: ['babel-polyfill', './src/player.js'], about: ['babel-polyfill', './src/about.js'] }, output: { path: resolve('dist'), // 指示发布目录 filename: 'js/[name].[chunkhash:8].js' //指示生成的页面入口js文件的目录和文件名, 中间包含8位的hash值 }, externals: { //video.js 作为外部资源引入 'video.js': 'videojs' }, //下面给一些常用组件和目录取别名, 方便在js中 import resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.common.js', 'jquery$': 'admin-lte/plugins/jQuery/jquery-2.2.3.min.js', 'src': resolve('src'), 'assets': resolve('src/assets'), 'components': resolve('src/components') } }, module: { //配置 webpack 加载资源的规则 rules: [{ test: /\.js$/, loader: 'babel-loader', include: [resolve('src')] }, { test: /\.vue$/, loader: 'vue-loader' }, { test: /\.css$/, loader: 'style-loader!css-loader' }, { test: /\.less$/, loader: "less-loader" }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader?limit=10000&name=images/[name].[hash:8].[ext]' }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader?limit=10000&name=fonts/[name].[hash:8].[ext]' }, { test: /\.(swf|mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader?limit=10000&name=media/[name].[hash:8].[ext]' }] }, plugins: [ //引入全局变量 new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', "window.jQuery": 'jquery', "window.$": 'jquery' }), new webpack.DllReferencePlugin({ context: __dirname, manifest: require('./dll/vendor-manifest.json') }), new CopyWebpackPlugin([ { from: 'dll', ignore: ['template.html', 'vendor-manifest.json'] } ]), //编译前先清除 dist 发布目录 new CleanWebpackPlugin(['dist']), //生成视频广场首页, 在这个页面中自动引用入口 index --> dist/js/index.[chunkhash:8].js //以 src/index.html 这个文件作为模板 new HtmlWebpackPlugin({ filename: 'index.html', title: '视频广场', inject: true, // head -> Cannot find element: #app chunks: ['index'], template: './dll/template.html', minify: { removeComments: true, collapseWhitespace: false } }), new HtmlWebpackPlugin({ filename: 'player.html', title: 'HLS 播放器', inject: true, chunks: ['player'], template: './dll/template.html', minify: { removeComments: true, collapseWhitespace: false } }), //生成版本信息页面, 在这个页面中自动引用入口 about --> dist/js/about.[chunkhash:8].js //以 src/index.html 这个文件作为模板 new HtmlWebpackPlugin({ filename: 'about.html', title: '版本信息', inject: true, chunks: ['about'], template: './dll/template.html', minify: { removeComments: true, collapseWhitespace: false } }) ]};
重点是在 externals 块下面声明 videojs 作为外部资源使用
然后, 我们添加一个新的静态页面配置, 用做 HLS 播放器的入口
打开 src/store/index.js, 修改如下:
import Vue from "vue";import Vuex from "vuex";Vue.use(Vuex);const store = new Vuex.Store({ state: { logoText: "EasyDSS", logoMiniText: "DSS", menus: [ { path: "/index.html", icon: "mouse-pointer", text: "视频广场" }, { path: "/player.html", icon: "play", text: "HLS 播放器" }, { path: "/about.html", icon: "support", text: "版本信息" } ] }, getters : { }, mutations: { }, actions : { }})export default store;
将 video.js 简单封装成组件, 新建 src/compontents/VideoJS.vue
封装 video.js api
编写播放器弹出框组件, 新建 src/components/VideoDlg.vue
封装 bootstrap 模态框
编写HLS播放器页面内容, 新建 src/components/Player.vue
这里顺带演示了 element-ui 的 Message 用法
点击播放按钮, 消息向父组件传递, 播放地址作为参数一起传递
编写入口 js , 新建 src/player.js
import Vue from 'vue'import store from "./store";import AdminLTE from './components/AdminLTE.vue'import Player from './components/Player.vue'import VideoDlg from './components/VideoDlg.vue'new Vue({ el: '#app', store, template: ``, components: { AdminLTE, Player, VideoDlg }, methods: { play(video){ this.$refs.videoDlg.play(video.videoUrl, video.videoTitle); } }})
接收 Player 组件传来的播放消息, 打开播放器弹出框, 完成视频播放
我们修改了 template.html 和 webpack.dll.config.js , 所以先要重新 build 共用组件库
npm run dll
然后
npm run start
WEB:www.liveqing.com
转载地址:http://sgvvi.baihongyu.com/