mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
Upgrade hls.js and set in low latency mode. v6.0.112 (#3924)
HLS typically has a delay of around 30 seconds, roughly comprising three segments, each lasting 10 seconds. We can reduce the delay to about 5 seconds by lowering the segment duration to 2 seconds and starting playback from the last segment, achieving a stable delay. Of course, this requires setting the OBS's GOP to 1 second, and the profile to baseline, preset to fast, and tune to zerolatency. Additionally, updating a few configurations in the hls.js player is necessary, such as setting it to start playback from the last segment, setting the maximum buffer, and initiating accelerated playback to reduce latency. --------- Co-authored-by: chundonglinlin <chundonglinlin@163.com> Co-authored-by: john <hondaxiao@tencent.com>
This commit is contained in:
parent
4ca7684e36
commit
22c2469414
16 changed files with 148 additions and 93 deletions
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
|
@ -276,7 +276,9 @@ jobs:
|
||||||
echo "Release ossrs/srs:$SRS_TAG"
|
echo "Release ossrs/srs:$SRS_TAG"
|
||||||
docker buildx build --platform linux/arm/v7,linux/arm64/v8,linux/amd64 \
|
docker buildx build --platform linux/arm/v7,linux/arm64/v8,linux/amd64 \
|
||||||
--output "type=image,push=true" \
|
--output "type=image,push=true" \
|
||||||
-t ossrs/srs:$SRS_TAG --build-arg SRS_AUTO_PACKAGER=$PACKAGER -f Dockerfile .
|
-t ossrs/srs:$SRS_TAG --build-arg SRS_AUTO_PACKAGER=$PACKAGER \
|
||||||
|
--build-arg CONFARGS='--sanitizer=off --gb28181=on' \
|
||||||
|
-f Dockerfile .
|
||||||
# Docker alias images
|
# Docker alias images
|
||||||
# TODO: FIXME: If stable, please set the latest from 5.0 to 6.0
|
# TODO: FIXME: If stable, please set the latest from 5.0 to 6.0
|
||||||
- name: Docker alias images for ossrs/srs
|
- name: Docker alias images for ossrs/srs
|
||||||
|
|
|
@ -29,7 +29,7 @@ WORKDIR /srs/trunk
|
||||||
# Build and install SRS.
|
# Build and install SRS.
|
||||||
# Note that SRT is enabled by default, so we configure without --srt=on.
|
# Note that SRT is enabled by default, so we configure without --srt=on.
|
||||||
# Note that we have copied all files by make install.
|
# Note that we have copied all files by make install.
|
||||||
RUN ./configure --sanitizer=off --gb28181=on --h265=on ${CONFARGS} && make ${MAKEARGS} && make install
|
RUN ./configure ${CONFARGS} && make ${MAKEARGS} && make install
|
||||||
|
|
||||||
############################################################
|
############################################################
|
||||||
# dist
|
# dist
|
||||||
|
|
|
@ -6,7 +6,7 @@ help=no
|
||||||
SRS_HDS=NO
|
SRS_HDS=NO
|
||||||
SRS_SRT=YES
|
SRS_SRT=YES
|
||||||
SRS_RTC=YES
|
SRS_RTC=YES
|
||||||
SRS_H265=NO
|
SRS_H265=YES
|
||||||
SRS_GB28181=NO
|
SRS_GB28181=NO
|
||||||
SRS_CXX11=YES
|
SRS_CXX11=YES
|
||||||
SRS_CXX14=NO
|
SRS_CXX14=NO
|
||||||
|
|
5
trunk/configure
vendored
5
trunk/configure
vendored
|
@ -648,9 +648,8 @@ install:
|
||||||
@mkdir -p \$(__REAL_INSTALL)
|
@mkdir -p \$(__REAL_INSTALL)
|
||||||
@echo "Now make the http root dir"
|
@echo "Now make the http root dir"
|
||||||
@mkdir -p \$(__REAL_INSTALL)/objs/nginx/html
|
@mkdir -p \$(__REAL_INSTALL)/objs/nginx/html
|
||||||
@cp -f research/api-server/static-dir/index.html \$(__REAL_INSTALL)/objs/nginx/html
|
@cp -f research/index.html \$(__REAL_INSTALL)/objs/nginx/html
|
||||||
@cp -f research/players/crossdomain.xml \$(__REAL_INSTALL)/objs/nginx/html
|
@cp -f research/favicon.ico \$(__REAL_INSTALL)/objs/nginx/html
|
||||||
@cp -f research/api-server/static-dir/favicon.ico \$(__REAL_INSTALL)/objs/nginx/html
|
|
||||||
@cp -Rf research/players \$(__REAL_INSTALL)/objs/nginx/html/
|
@cp -Rf research/players \$(__REAL_INSTALL)/objs/nginx/html/
|
||||||
@cp -Rf research/console \$(__REAL_INSTALL)/objs/nginx/html/
|
@cp -Rf research/console \$(__REAL_INSTALL)/objs/nginx/html/
|
||||||
@cp -Rf 3rdparty/signaling/www/demos \$(__REAL_INSTALL)/objs/nginx/html/
|
@cp -Rf 3rdparty/signaling/www/demos \$(__REAL_INSTALL)/objs/nginx/html/
|
||||||
|
|
|
@ -7,6 +7,7 @@ The changelog for SRS.
|
||||||
<a name="v6-changes"></a>
|
<a name="v6-changes"></a>
|
||||||
|
|
||||||
## SRS 6.0 Changelog
|
## SRS 6.0 Changelog
|
||||||
|
* v6.0, 2024-02-05, Merge [#3924](https://github.com/ossrs/srs/pull/3924): Upgrade hls.js and set in low latency mode. v6.0.112 (#3924)
|
||||||
* v6.0, 2024-02-05, Merge [#3925](https://github.com/ossrs/srs/pull/3925): RTC: Fix video and audio track pt_ is not change in player before publisher. v6.0.111 (#3925)
|
* v6.0, 2024-02-05, Merge [#3925](https://github.com/ossrs/srs/pull/3925): RTC: Fix video and audio track pt_ is not change in player before publisher. v6.0.111 (#3925)
|
||||||
* v6.0, 2024-02-05, Merge [#3923](https://github.com/ossrs/srs/pull/3923): Configure: print enabled/disable sanitizer. v6.0.110 (#3923)
|
* v6.0, 2024-02-05, Merge [#3923](https://github.com/ossrs/srs/pull/3923): Configure: print enabled/disable sanitizer. v6.0.110 (#3923)
|
||||||
* v6.0, 2023-12-30, Merge [#3916](https://github.com/ossrs/srs/pull/3916): Enhancing the compatibility of options.sh. v6.0.108 (#3916)
|
* v6.0, 2023-12-30, Merge [#3916](https://github.com/ossrs/srs/pull/3916): Enhancing the compatibility of options.sh. v6.0.108 (#3916)
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 17 B |
1
trunk/research/api-server/static-dir/favicon.ico
Symbolic link
1
trunk/research/api-server/static-dir/favicon.ico
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../favicon.ico
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 17 B |
|
@ -1,72 +0,0 @@
|
||||||
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>SRS</title>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<style>
|
|
||||||
.span6 {
|
|
||||||
width: 480px;
|
|
||||||
}
|
|
||||||
.code {
|
|
||||||
background-color: rgb(246 248 250);
|
|
||||||
padding: 8px;
|
|
||||||
overflow: auto;
|
|
||||||
font-size: 85%;
|
|
||||||
line-height: 1.45;
|
|
||||||
border-radius: 6px;
|
|
||||||
word-break: normal;
|
|
||||||
word-wrap: normal;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: block;
|
|
||||||
white-space: pre;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div>
|
|
||||||
<h3><a href="https://github.com/ossrs/srs">SRS</a> works!</h3>
|
|
||||||
<p>
|
|
||||||
Click <a id="enConsole" href="#">here</a> to enter SRS console.<br/>
|
|
||||||
点击进入<a id="cnConsole" href="#">SRS控制台</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Publish stream by <a href="https://ffmpeg.org/download.html">FFmpeg</a> or <a href="https://obsproject.com/download">OBS</a>:<br/>
|
|
||||||
请使用工具<a href="https://ffmpeg.org/download.html">FFmpeg</a>或者<a href="https://obsproject.com/download">OBS</a>推流到下面地址:
|
|
||||||
<pre id="url" class="code span6"></pre>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Click <a id="enPlayer" href="#">here</a> to start SRS player.<br/>
|
|
||||||
点击进入<a id="cnPlayer" href="#">SRS播放器</a>
|
|
||||||
</p>
|
|
||||||
<p><a href="https://github.com/ossrs/srs">SRS Team © 2022</a></p>
|
|
||||||
</div>
|
|
||||||
<script type="text/javascript">
|
|
||||||
// Build RTMP url.
|
|
||||||
if (true) {
|
|
||||||
const rtmpUrl = `rtmp://${window.location.hostname}/live/livestream`;
|
|
||||||
document.getElementById('url').innerText = rtmpUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build console url.
|
|
||||||
if (true) {
|
|
||||||
// The prefix for default website.
|
|
||||||
const prefix = `${window.location.protocol}//${window.location.host}`;
|
|
||||||
// If not 8080, user should proxy to the default port.
|
|
||||||
const query = parseInt(window.location.port) === 8080 ? `?port=1985` : '';
|
|
||||||
const enUrl = `${prefix}/console/en_index.html#/summaries${query}`;
|
|
||||||
const cnUrl = `${prefix}/console/ng_index.html#/summaries${query}`;
|
|
||||||
document.getElementById("enConsole").setAttribute('href', enUrl);
|
|
||||||
document.getElementById("cnConsole").setAttribute('href', cnUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The player url.
|
|
||||||
if (true) {
|
|
||||||
const prefix = `players/?schema=${window.location.protocol.replace(':', '')}`;
|
|
||||||
const httpPort = window.location.port || (window.location.protocol === 'http:' ? 80 : 443);
|
|
||||||
// If not 8080, user should proxy both stream and API to the default port.
|
|
||||||
const query = parseInt(window.location.port) === 8080 ? '' : `&port=${httpPort}&api=${httpPort}`;
|
|
||||||
document.getElementById("enPlayer").setAttribute('href', `${prefix}${query}`);
|
|
||||||
document.getElementById("cnPlayer").setAttribute('href', `${prefix}${query}`);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
1
trunk/research/api-server/static-dir/index.html
Symbolic link
1
trunk/research/api-server/static-dir/index.html
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../index.html
|
BIN
trunk/research/favicon.ico
Normal file
BIN
trunk/research/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
103
trunk/research/index.html
Executable file
103
trunk/research/index.html
Executable file
|
@ -0,0 +1,103 @@
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>SRS</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<style>
|
||||||
|
.code {
|
||||||
|
background-color: rgb(217, 222, 227);
|
||||||
|
padding: 2px;
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 85%;
|
||||||
|
line-height: 1.45;
|
||||||
|
border-radius: 6px;
|
||||||
|
word-break: normal;
|
||||||
|
word-wrap: normal;
|
||||||
|
box-sizing: border-box;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<h2>Status</h2>
|
||||||
|
<p>Congratulations! <a href="https://github.com/ossrs/srs">SRS</a> works!</p>
|
||||||
|
<hr/>
|
||||||
|
<h2>English</h2>
|
||||||
|
<p>
|
||||||
|
1. Please publish stream by:
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
Recommend <a href="https://obsproject.com/download">OBS</a>, set Service to <span class="code">Custom</span>,
|
||||||
|
set Server to <span id="url3" class="code"></span>
|
||||||
|
and Stream Key to <span id="url4" class="code"></span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
You can also use <a href="https://ffmpeg.org/download.html">FFmpeg</a>:
|
||||||
|
<span id="url" class="code"></span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Or use WHIP to publish stream, please click <span class="code">SRS Player</span> link below.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
<p>2. Choose <a id="enPlayer" href="#">SRS player</a> to play the stream in different protocols.</p>
|
||||||
|
<p>3. (Optional) Click <a id="enConsole" href="#">here</a> to enter SRS console.</p>
|
||||||
|
<hr/>
|
||||||
|
<h2>简体中文</h2>
|
||||||
|
<p>
|
||||||
|
1. 请选择推流方式:
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
推荐<a href="https://obsproject.com/download">OBS</a>,设置服务为 <span class="code">自定义</span>,
|
||||||
|
设置推流地址(服务器)为 <span id="url5" class="code"></span>,
|
||||||
|
设置推流密钥(串流密钥)为 <span id="url6" class="code"></span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
或者用<a href="https://ffmpeg.org/download.html">FFmpeg</a>推流到地址:
|
||||||
|
<span id="url2" class="code"></span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
或者使用WHIP推流,请点击下面的 <span class="code">SRS播放器</span> 链接。
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
<p>2. 点击选择 <a id="cnPlayer" href="#">SRS播放器</a></p>
|
||||||
|
<p>3. 点击进入 <a id="cnConsole" href="#">SRS控制台</a> (可选) </p>
|
||||||
|
<hr/>
|
||||||
|
<p><a href="https://github.com/ossrs/srs">SRS Team © 2013~2024</a></p>
|
||||||
|
</div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
// Build RTMP url.
|
||||||
|
if (true) {
|
||||||
|
const server = `rtmp://${window.location.hostname}/live`;
|
||||||
|
const key = `livestream`;
|
||||||
|
const rtmpUrl = `${server}/${key}`;
|
||||||
|
document.getElementById('url2').innerText = document.getElementById('url').innerText = `ffmpeg -re -i ./doc/source.200kbps.768x320.flv -c copy -f flv ${rtmpUrl}`;
|
||||||
|
document.getElementById('url5').innerText = document.getElementById('url3').innerText = server;
|
||||||
|
document.getElementById('url6').innerText = document.getElementById('url4').innerText = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build console url.
|
||||||
|
if (true) {
|
||||||
|
// The prefix for default website.
|
||||||
|
const prefix = `${window.location.protocol}//${window.location.host}`;
|
||||||
|
// If not 8080, user should proxy to the default port.
|
||||||
|
const query = parseInt(window.location.port) === 8080 ? `?port=1985` : '';
|
||||||
|
const enUrl = `${prefix}/console/en_index.html#/summaries${query}`;
|
||||||
|
const cnUrl = `${prefix}/console/ng_index.html#/summaries${query}`;
|
||||||
|
document.getElementById("enConsole").setAttribute('href', enUrl);
|
||||||
|
document.getElementById("cnConsole").setAttribute('href', cnUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The player url.
|
||||||
|
if (true) {
|
||||||
|
const prefix = `players/?schema=${window.location.protocol.replace(':', '')}`;
|
||||||
|
const httpPort = window.location.port || (window.location.protocol === 'http:' ? 80 : 443);
|
||||||
|
// If not 8080, user should proxy both stream and API to the default port.
|
||||||
|
const query = parseInt(window.location.port) === 8080 ? '' : `&port=${httpPort}&api=${httpPort}`;
|
||||||
|
document.getElementById("enPlayer").setAttribute('href', `${prefix}${query}`);
|
||||||
|
document.getElementById("cnPlayer").setAttribute('href', `${prefix}${query}`);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
2
trunk/research/players/js/hls-0.14.17.min.js
vendored
2
trunk/research/players/js/hls-0.14.17.min.js
vendored
File diff suppressed because one or more lines are too long
2
trunk/research/players/js/hls-1.4.14.min.js
vendored
Normal file
2
trunk/research/players/js/hls-1.4.14.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -103,7 +103,7 @@
|
||||||
<script type="text/javascript" src="js/jquery-1.12.2.min.js"></script>
|
<script type="text/javascript" src="js/jquery-1.12.2.min.js"></script>
|
||||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||||
<script type="text/javascript" src="js/mpegts-1.7.3.min.js"></script>
|
<script type="text/javascript" src="js/mpegts-1.7.3.min.js"></script>
|
||||||
<script type="text/javascript" src="js/hls-0.14.17.min.js"></script>
|
<script type="text/javascript" src="js/hls-1.4.14.min.js"></script>
|
||||||
<script type="text/javascript" src="js/dash-v4.5.1.all.min.js"></script>
|
<script type="text/javascript" src="js/dash-v4.5.1.all.min.js"></script>
|
||||||
<script type="text/javascript" src="js/json2.js"></script>
|
<script type="text/javascript" src="js/json2.js"></script>
|
||||||
<script type="text/javascript" src="js/srs.page.js"></script>
|
<script type="text/javascript" src="js/srs.page.js"></script>
|
||||||
|
@ -196,6 +196,8 @@
|
||||||
stopPlayers();
|
stopPlayers();
|
||||||
if (!r) return;
|
if (!r) return;
|
||||||
|
|
||||||
|
const video = document.getElementById('video_player');
|
||||||
|
|
||||||
// Use H5 native to play aac/mp3.
|
// Use H5 native to play aac/mp3.
|
||||||
if (r.stream.indexOf('.mp3') > 0 || r.stream.indexOf('.aac') > 0) {
|
if (r.stream.indexOf('.mp3') > 0 || r.stream.indexOf('.aac') > 0) {
|
||||||
$('#audio_player').attr('src', r.url).show();
|
$('#audio_player').attr('src', r.url).show();
|
||||||
|
@ -220,7 +222,7 @@
|
||||||
show_for_video_ok();
|
show_for_video_ok();
|
||||||
|
|
||||||
tsPlayer = mpegts.createPlayer({type: 'mpegts', url: r.url, isLive: true, enableStashBuffer: false});
|
tsPlayer = mpegts.createPlayer({type: 'mpegts', url: r.url, isLive: true, enableStashBuffer: false});
|
||||||
tsPlayer.attachMediaElement(document.getElementById('video_player'));
|
tsPlayer.attachMediaElement(video);
|
||||||
tsPlayer.load();
|
tsPlayer.load();
|
||||||
tsPlayer.play();
|
tsPlayer.play();
|
||||||
return;
|
return;
|
||||||
|
@ -235,9 +237,21 @@
|
||||||
|
|
||||||
show_for_video_ok();
|
show_for_video_ok();
|
||||||
|
|
||||||
hlsPlayer = new Hls();
|
// See https://github.com/video-dev/hls.js/blob/master/docs/API.md#maxlivesyncplaybackrate
|
||||||
|
// See https://github.com/video-dev/hls.js/issues/3077#issuecomment-705152394
|
||||||
|
hlsPlayer = new Hls({
|
||||||
|
enableWorker: true, // Improve performance and avoid lag/frame drops.
|
||||||
|
lowLatencyMode: true, // Enable Low-Latency HLS part playlist and segment loading.
|
||||||
|
liveSyncDurationCount: 0, // Start from the last segment.
|
||||||
|
liveMaxLatencyDurationCount: 4, // Maximum delay allowed from edge of live.
|
||||||
|
maxBufferLength: 5, // Maximum buffer length in seconds.
|
||||||
|
maxMaxBufferLength: 8, // The max Maximum buffer length in seconds.
|
||||||
|
maxLiveSyncPlaybackRate: 2, // Catch up if the latency is large.
|
||||||
|
liveDurationInfinity: true // Override current Media Source duration to Infinity for a live broadcast.
|
||||||
|
});
|
||||||
hlsPlayer.loadSource(r.url);
|
hlsPlayer.loadSource(r.url);
|
||||||
hlsPlayer.attachMedia(document.getElementById('video_player'));
|
hlsPlayer.attachMedia(video);
|
||||||
|
video.play();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,16 +278,23 @@
|
||||||
|
|
||||||
show_for_video_ok();
|
show_for_video_ok();
|
||||||
|
|
||||||
flvPlayer = mpegts.createPlayer({type: 'flv', url: r.url, isLive: true, enableStashBuffer: false});
|
// See https://github.com/xqq/mpegts.js/blob/master/src/config.js#L32
|
||||||
flvPlayer.attachMediaElement(document.getElementById('video_player'));
|
// See https://github.com/xqq/mpegts.js/blob/master/docs/api.md
|
||||||
|
flvPlayer = mpegts.createPlayer({
|
||||||
|
type: 'flv', url: r.url,
|
||||||
|
isLive: true, enableStashBuffer: false, liveSync: true
|
||||||
|
});
|
||||||
|
flvPlayer.attachMediaElement(video);
|
||||||
flvPlayer.load();
|
flvPlayer.load();
|
||||||
flvPlayer.play();
|
flvPlayer.play();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error('不支持的URL', r.url, r);
|
|
||||||
$('#video_player').hide();
|
$('#video_player').hide();
|
||||||
$('#audio_player').hide();
|
|
||||||
|
const msg = `Not supported URL ${r.url} ${JSON.stringify(r)}`;
|
||||||
|
console.error(msg);
|
||||||
|
alert(msg);
|
||||||
};
|
};
|
||||||
|
|
||||||
$("#txt_url").change(function(){
|
$("#txt_url").change(function(){
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
|
|
||||||
#define VERSION_MAJOR 6
|
#define VERSION_MAJOR 6
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 111
|
#define VERSION_REVISION 112
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue