HTTP-FLV player for low latency (expermiental)
This commit is contained in:
parent
6ca6a5424f
commit
1def826e8e
38
docs/srs.conf
Normal file
38
docs/srs.conf
Normal file
@ -0,0 +1,38 @@
|
||||
# srs HTTP-FLV example
|
||||
|
||||
listen 1935;
|
||||
max_connections 1000;
|
||||
daemon off;
|
||||
srs_log_tank console;
|
||||
http_server {
|
||||
enabled on;
|
||||
listen 127.0.0.1:8080;
|
||||
dir ./objs/nginx/html;
|
||||
}
|
||||
|
||||
vhost preview.local {
|
||||
# needs redirect in /etc/hosts:
|
||||
# 127.0.0.1 preview.local
|
||||
http_remux {
|
||||
enabled on;
|
||||
mount [vhost]/[app]/[stream].flv;
|
||||
}
|
||||
|
||||
# low latency:
|
||||
# tcp_nodelay on
|
||||
# min_latency on;
|
||||
|
||||
# play {
|
||||
# gop_cache off;
|
||||
# queue_length 10;
|
||||
# mw_latency 100;
|
||||
# }
|
||||
|
||||
# publish {
|
||||
# mr off;
|
||||
# }
|
||||
}
|
||||
|
||||
vhost __defaultVhost__ {
|
||||
|
||||
}
|
51
package-lock.json
generated
51
package-lock.json
generated
@ -16,6 +16,7 @@
|
||||
"cookie-universal-nuxt": "^2.1.5",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"lodash": "^4.17.21",
|
||||
"mpegts.js": "^1.6.10",
|
||||
"nuxt": "^2.15.8",
|
||||
"splitpanes": "^2.3.8",
|
||||
"video.js": "^7.17.0",
|
||||
@ -6154,6 +6155,11 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/es6-promise": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
||||
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||
@ -9765,6 +9771,15 @@
|
||||
"mpd-to-m3u8-json": "bin/parse.js"
|
||||
}
|
||||
},
|
||||
"node_modules/mpegts.js": {
|
||||
"version": "1.6.10",
|
||||
"resolved": "https://registry.npmjs.org/mpegts.js/-/mpegts.js-1.6.10.tgz",
|
||||
"integrity": "sha512-ZgX4b93cWk+EazOFRV4lekLqmc4rV7P+WMisG8N0F2M4/EiluPMNNWjuaurQfitak++AIc/ZVQ3IgM3cBcH7WA==",
|
||||
"dependencies": {
|
||||
"es6-promise": "^4.2.5",
|
||||
"webworkify-webpack": "^2.1.5"
|
||||
}
|
||||
},
|
||||
"node_modules/mrmime": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz",
|
||||
@ -14551,9 +14566,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ufo": {
|
||||
"version": "0.7.9",
|
||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-0.7.9.tgz",
|
||||
"integrity": "sha512-6t9LrLk3FhqTS+GW3IqlITtfRB5JAVr5MMNjpBECfK827W+Vh5Ilw/LhTcHWrt6b3hkeBvcbjx4Ti7QVFzmcww=="
|
||||
"version": "0.7.10",
|
||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-0.7.10.tgz",
|
||||
"integrity": "sha512-YTnDRlE1cIofRqOFN8ioAbz9qenDvkgVMSn0cnxvIDjM9sfEOMKB0ybMr+otSlCXMfQ/X35haYRoI7Nua82RrA=="
|
||||
},
|
||||
"node_modules/uglify-js": {
|
||||
"version": "3.15.0",
|
||||
@ -16320,6 +16335,11 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/webworkify-webpack": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/webworkify-webpack/-/webworkify-webpack-2.1.5.tgz",
|
||||
"integrity": "sha512-2akF8FIyUvbiBBdD+RoHpoTbHMQF2HwjcxfDvgztAX5YwbZNyrtfUMgvfgFVsgDhDPVTlkbb5vyasqDHfIDPQw=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
@ -21343,6 +21363,11 @@
|
||||
"is-symbol": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
||||
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
|
||||
},
|
||||
"escalade": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||
@ -24056,6 +24081,15 @@
|
||||
"global": "^4.4.0"
|
||||
}
|
||||
},
|
||||
"mpegts.js": {
|
||||
"version": "1.6.10",
|
||||
"resolved": "https://registry.npmjs.org/mpegts.js/-/mpegts.js-1.6.10.tgz",
|
||||
"integrity": "sha512-ZgX4b93cWk+EazOFRV4lekLqmc4rV7P+WMisG8N0F2M4/EiluPMNNWjuaurQfitak++AIc/ZVQ3IgM3cBcH7WA==",
|
||||
"requires": {
|
||||
"es6-promise": "^4.2.5",
|
||||
"webworkify-webpack": "^2.1.5"
|
||||
}
|
||||
},
|
||||
"mrmime": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz",
|
||||
@ -27819,9 +27853,9 @@
|
||||
"integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ=="
|
||||
},
|
||||
"ufo": {
|
||||
"version": "0.7.9",
|
||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-0.7.9.tgz",
|
||||
"integrity": "sha512-6t9LrLk3FhqTS+GW3IqlITtfRB5JAVr5MMNjpBECfK827W+Vh5Ilw/LhTcHWrt6b3hkeBvcbjx4Ti7QVFzmcww=="
|
||||
"version": "0.7.10",
|
||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-0.7.10.tgz",
|
||||
"integrity": "sha512-YTnDRlE1cIofRqOFN8ioAbz9qenDvkgVMSn0cnxvIDjM9sfEOMKB0ybMr+otSlCXMfQ/X35haYRoI7Nua82RrA=="
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "3.15.0",
|
||||
@ -29212,6 +29246,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"webworkify-webpack": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/webworkify-webpack/-/webworkify-webpack-2.1.5.tgz",
|
||||
"integrity": "sha512-2akF8FIyUvbiBBdD+RoHpoTbHMQF2HwjcxfDvgztAX5YwbZNyrtfUMgvfgFVsgDhDPVTlkbb5vyasqDHfIDPQw=="
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
|
@ -20,6 +20,7 @@
|
||||
"cookie-universal-nuxt": "^2.1.5",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"lodash": "^4.17.21",
|
||||
"mpegts.js": "^1.6.10",
|
||||
"nuxt": "^2.15.8",
|
||||
"splitpanes": "^2.3.8",
|
||||
"video.js": "^7.17.0",
|
||||
|
@ -5,7 +5,13 @@
|
||||
<b-row class="control-row">
|
||||
<b-col cols="3" class="player-col">
|
||||
<b-aspect aspect="16:9">
|
||||
<video-player v-if="videoOptions.sources" :key="configID" reference="videoPlayer" :options="videoOptions" />
|
||||
<video
|
||||
v-if="configGui[configID].player_url.split('.').pop() === 'flv'"
|
||||
id="httpStream"
|
||||
ref="httpStream"
|
||||
controls
|
||||
/>
|
||||
<video-player v-else-if="videoOptions.sources" :key="configID" reference="videoPlayer" :options="videoOptions" />
|
||||
</b-aspect>
|
||||
</b-col>
|
||||
<b-col class="control-col">
|
||||
@ -308,6 +314,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import mpegts from 'mpegts.js'
|
||||
/* eslint-disable vue/custom-event-name-casing */
|
||||
import { mapState } from 'vuex'
|
||||
import Menu from '@/components/Menu.vue'
|
||||
@ -358,6 +365,17 @@ export default {
|
||||
preload: 'auto',
|
||||
sources: []
|
||||
},
|
||||
httpFlvSource: {
|
||||
type: 'flv',
|
||||
isLive: true,
|
||||
url: ''
|
||||
},
|
||||
mpegtsOptions: {
|
||||
enableWorker: true,
|
||||
lazyLoadMaxDuration: 3 * 60,
|
||||
seekType: 'range',
|
||||
liveBufferLatencyChasing: true
|
||||
},
|
||||
previewOptions: {},
|
||||
previewComp: null,
|
||||
previewSource: '',
|
||||
@ -436,6 +454,27 @@ export default {
|
||||
this.$store.dispatch('playlist/animClock')
|
||||
}
|
||||
|
||||
const streamExtension = this.configGui[this.configID].player_url.split('.').pop()
|
||||
let player
|
||||
|
||||
if (streamExtension === 'flv') {
|
||||
this.httpFlvSource.url = this.configGui[this.configID].player_url
|
||||
const element = this.$refs.httpStream
|
||||
|
||||
if (typeof player !== 'undefined') {
|
||||
if (player != null) {
|
||||
player.unload()
|
||||
player.detachMediaElement()
|
||||
player.destroy()
|
||||
player = null
|
||||
}
|
||||
}
|
||||
|
||||
player = mpegts.createPlayer(this.httpFlvSource, this.mpegtsOptions)
|
||||
player.attachMediaElement(element)
|
||||
player.load()
|
||||
}
|
||||
|
||||
setTimeout(() => { scrollTo(this) }, 4000)
|
||||
},
|
||||
|
||||
|
63
test.html
Normal file
63
test.html
Normal file
@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>videojs</title>
|
||||
<link href="https://unpkg.com/video.js@7.7.5/dist/video-js.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<video-js id="my-video" class="video-js" autoplay muted preload="auto" data-setup="">
|
||||
</video-js>
|
||||
|
||||
<script src="https://unpkg.com/video.js@7.7.5/dist/video.min.js"></script>
|
||||
<script src="https://unpkg.com/flv.js@1.5.0/dist/flv.min.js"></script>
|
||||
<script src="https://unpkg.com/videojs-flvjs@0.2.0/dist/videojs-flvjs.min.js"></script>
|
||||
|
||||
<script>
|
||||
var player = videojs(
|
||||
"my-video",
|
||||
{
|
||||
controls: false,
|
||||
bigPlayButton: false,
|
||||
autoplay: 'muted',
|
||||
preload: 'auto',
|
||||
width: 800,
|
||||
height: 640,
|
||||
flvjs: {
|
||||
mediaDataSource: {
|
||||
isLive: true,
|
||||
withCredentials: false,
|
||||
hasAudio: false,
|
||||
hasVideo: true,
|
||||
type: 'flv'
|
||||
},
|
||||
config: {
|
||||
enableStashBuffer: true,
|
||||
enableWorker: false,
|
||||
lazyLoad: false,
|
||||
seekType: 'range'
|
||||
}
|
||||
},
|
||||
},
|
||||
function onPlayerReady() {
|
||||
videojs.log("Your player is ready!");
|
||||
console.log(this
|
||||
.tech({ IWillNotUseThisInPlugins: true }))
|
||||
this
|
||||
.tech({ IWillNotUseThisInPlugins: true })
|
||||
.flvPlayer.on(flvjs.Events.STATISTICS_INFO, (metadata) =>
|
||||
console.log(metadata)
|
||||
);
|
||||
}
|
||||
);
|
||||
player.src({
|
||||
fluid: true,
|
||||
src: 'http://ffplayout.local/preview/stream.flv',
|
||||
type: 'video/x-flv'
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user