HTTP-FLV player for low latency (expermiental)

This commit is contained in:
jonathan 2022-01-31 17:40:13 +01:00
parent 6ca6a5424f
commit 1def826e8e
5 changed files with 187 additions and 7 deletions

38
docs/srs.conf Normal file
View 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
View File

@ -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",

View File

@ -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",

View File

@ -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
View 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>