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",
|
"cookie-universal-nuxt": "^2.1.5",
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"mpegts.js": "^1.6.10",
|
||||||
"nuxt": "^2.15.8",
|
"nuxt": "^2.15.8",
|
||||||
"splitpanes": "^2.3.8",
|
"splitpanes": "^2.3.8",
|
||||||
"video.js": "^7.17.0",
|
"video.js": "^7.17.0",
|
||||||
@ -6154,6 +6155,11 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"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": {
|
"node_modules/escalade": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||||
@ -9765,6 +9771,15 @@
|
|||||||
"mpd-to-m3u8-json": "bin/parse.js"
|
"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": {
|
"node_modules/mrmime": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz",
|
||||||
@ -14551,9 +14566,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ufo": {
|
"node_modules/ufo": {
|
||||||
"version": "0.7.9",
|
"version": "0.7.10",
|
||||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-0.7.9.tgz",
|
"resolved": "https://registry.npmjs.org/ufo/-/ufo-0.7.10.tgz",
|
||||||
"integrity": "sha512-6t9LrLk3FhqTS+GW3IqlITtfRB5JAVr5MMNjpBECfK827W+Vh5Ilw/LhTcHWrt6b3hkeBvcbjx4Ti7QVFzmcww=="
|
"integrity": "sha512-YTnDRlE1cIofRqOFN8ioAbz9qenDvkgVMSn0cnxvIDjM9sfEOMKB0ybMr+otSlCXMfQ/X35haYRoI7Nua82RrA=="
|
||||||
},
|
},
|
||||||
"node_modules/uglify-js": {
|
"node_modules/uglify-js": {
|
||||||
"version": "3.15.0",
|
"version": "3.15.0",
|
||||||
@ -16320,6 +16335,11 @@
|
|||||||
"node": ">=8"
|
"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": {
|
"node_modules/whatwg-url": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
@ -21343,6 +21363,11 @@
|
|||||||
"is-symbol": "^1.0.2"
|
"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": {
|
"escalade": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
|
||||||
@ -24056,6 +24081,15 @@
|
|||||||
"global": "^4.4.0"
|
"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": {
|
"mrmime": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz",
|
||||||
@ -27819,9 +27853,9 @@
|
|||||||
"integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ=="
|
"integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ=="
|
||||||
},
|
},
|
||||||
"ufo": {
|
"ufo": {
|
||||||
"version": "0.7.9",
|
"version": "0.7.10",
|
||||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-0.7.9.tgz",
|
"resolved": "https://registry.npmjs.org/ufo/-/ufo-0.7.10.tgz",
|
||||||
"integrity": "sha512-6t9LrLk3FhqTS+GW3IqlITtfRB5JAVr5MMNjpBECfK827W+Vh5Ilw/LhTcHWrt6b3hkeBvcbjx4Ti7QVFzmcww=="
|
"integrity": "sha512-YTnDRlE1cIofRqOFN8ioAbz9qenDvkgVMSn0cnxvIDjM9sfEOMKB0ybMr+otSlCXMfQ/X35haYRoI7Nua82RrA=="
|
||||||
},
|
},
|
||||||
"uglify-js": {
|
"uglify-js": {
|
||||||
"version": "3.15.0",
|
"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": {
|
"whatwg-url": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"cookie-universal-nuxt": "^2.1.5",
|
"cookie-universal-nuxt": "^2.1.5",
|
||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"mpegts.js": "^1.6.10",
|
||||||
"nuxt": "^2.15.8",
|
"nuxt": "^2.15.8",
|
||||||
"splitpanes": "^2.3.8",
|
"splitpanes": "^2.3.8",
|
||||||
"video.js": "^7.17.0",
|
"video.js": "^7.17.0",
|
||||||
|
@ -5,7 +5,13 @@
|
|||||||
<b-row class="control-row">
|
<b-row class="control-row">
|
||||||
<b-col cols="3" class="player-col">
|
<b-col cols="3" class="player-col">
|
||||||
<b-aspect aspect="16:9">
|
<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-aspect>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col class="control-col">
|
<b-col class="control-col">
|
||||||
@ -308,6 +314,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import mpegts from 'mpegts.js'
|
||||||
/* eslint-disable vue/custom-event-name-casing */
|
/* eslint-disable vue/custom-event-name-casing */
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import Menu from '@/components/Menu.vue'
|
import Menu from '@/components/Menu.vue'
|
||||||
@ -358,6 +365,17 @@ export default {
|
|||||||
preload: 'auto',
|
preload: 'auto',
|
||||||
sources: []
|
sources: []
|
||||||
},
|
},
|
||||||
|
httpFlvSource: {
|
||||||
|
type: 'flv',
|
||||||
|
isLive: true,
|
||||||
|
url: ''
|
||||||
|
},
|
||||||
|
mpegtsOptions: {
|
||||||
|
enableWorker: true,
|
||||||
|
lazyLoadMaxDuration: 3 * 60,
|
||||||
|
seekType: 'range',
|
||||||
|
liveBufferLatencyChasing: true
|
||||||
|
},
|
||||||
previewOptions: {},
|
previewOptions: {},
|
||||||
previewComp: null,
|
previewComp: null,
|
||||||
previewSource: '',
|
previewSource: '',
|
||||||
@ -436,6 +454,27 @@ export default {
|
|||||||
this.$store.dispatch('playlist/animClock')
|
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)
|
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