Recommended other players:
- flv.js, HTML5/MSE for playing HTTP-FLV
- mpegts.js, HTML5/MSE for playing HTTP-TS
- hls.js, HTML5/MSE for playing HLS
- dash.js, HTML5/MSE for playing MPEG-DASH
Hi!
I managed to stream the video from the smartphone to the srs live stream:
(base) raphy@raohy:~/.talos/srs-realtimevideostreaming$ CANDIDATE="192.168.1.68"
(base) raphy@raohy:~$ sudo docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 -p 1990:1990 -p 8088:8088 \
> --env CANDIDATE=$CANDIDATE -p 8000:8000/udp \
> ossrs/srs:5 ./objs/srs -c conf/https.docker.conf
Now I want to use instead of http://localhost:8080/live/livestream.flv in the Live Player:
something like :
http://srs.myserver.name:8080/live/livestream.flv in the Live Player
Is this possible?
This is what I've done:
nginx.conf
:
(base) raphy@raohy:~/.talos/nginx$ cat conf/nginx.conf
# https://github.com/ossrs/srs/blob/develop/trunk/conf/https.rtc.conf
# https://stackoverflow.com/questions/42078080/add-nginx-conf-to-kubernetes-cluster
listen 1935;
max_connections 1000;
daemon off;
srs_log_tank console;
http_server {
server_name srs.grasp.deals;
enabled on;
listen 8080;
dir ./srs_player.html;
https {
enabled on;
listen 8088;
key ./conf/server.key;
cert ./conf/server.crt;
}
}
http_api {
enabled on;
listen 1985;
https {
enabled on;
listen 1990;
key ./conf/server.key;
cert ./conf/server.crt;
}
}
stats {
network 0;
}
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}
vhost __defaultVhost__ {
rtc {
enabled on;
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc off;
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp off;
}
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
}
srs-player.html
file :
<!DOCTYPE html>
<html>
<head>
<title>SRS</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css"/>
<style>
body{
padding-top: 30px;
}
</style>
</head>
<body>
<img src='//ossrs.net/gif/v1/sls.gif?site=ossrs.net&path=/player/srsplayer'/>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="https://github.com/ossrs/srs" target="_blank">SRS</a>
<div class="nav-collapse collapse">
<ul class="nav">
<li class="active"><a id="nav_srs_player" href="srs_player.html">LivePlayer</a></li>
<li><a id="nav_whip" href="whip.html">WHIP</a></li>
<li><a id="nav_whep" href="whip.html">WHEP</a></li>
<li><a href="http://ossrs.net/srs.release/releases/app.html">iOS/Andriod</a></li>
<!--<li><a id="nav_gb28181" href="srs_gb28181.html">GB28181</a></li>-->
<!--<li>
<a href="https://github.com/ossrs/srs">
<img alt="GitHub Repo stars" src="https://img.shields.io/github/stars/ossrs/srs?style=social">
</a>
</li>-->
</ul>
</div>
</div>
</div>
</div>
<div class="container">
<div id="main_content">
<div id="main_info" class="alert alert-info fade in">
×
Usage: Enter the HTTP-FLV/HLS URL and click "Play" to start playing the video.
Share: Please right-click and copy this link.
Recommended other players:
<div name="detect_flash">
<div id="main_flash_alert" class="alert alert-danger fade in hide">
Create a button element with the class "close" that, when clicked, will dismiss an alert component. The button contains a multiplication sign (×) as its visual representation.
Create a hyperlink that says "Flash is dead," which directs to Adobe's webpage providing information about the end of life for Flash Player. This link is intended to open in a new browser tab.
Unable to play RTMP streams, you can use ffplay or VLC player to play.
For additional information, refer to the hyperlink titled "How to conduct live streaming without Flash?" which leads to an article on the WeChat platform. This link is designed to open in a new browser tab.
<footer>
<p></p>
<p><a href="https://github.com/ossrs/srs">SRS Team © 2013</a></p>
</footer>
</div>
</body>
<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/mpegts-1.7.2.min.js"></script>
<script type="text/javascript" src="js/hls-0.14.17.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/srs.page.js"></script>
<script type="text/javascript" src="js/srs.log.js"></script>
<script type="text/javascript" src="js/srs.utility.js"></script>
<script type="text/javascript" src="js/winlin.utility.js"></script>
<script type="text/javascript">
var flvPlayer = null;
var tsPlayer = null;
var hlsPlayer = null;
var dashPlayer = null;
var stopPlayers = function () {
if (flvPlayer) {
flvPlayer.destroy();
flvPlayer = null;
}
if (tsPlayer) {
tsPlayer.destroy();
tsPlayer = null;
}
if (hlsPlayer) {
hlsPlayer.destroy();
hlsPlayer = null;
}
if (dashPlayer) {
dashPlayer.destroy();
dashPlayer = null;
}
};
var hide_for_error = function () {
$('#main_flash_alert').show();
$('#main_info').hide();
$('#main_tips').hide();
$('#video_player').hide();
//$('#btn_play').hide();
stopPlayers();
};
var show_for_ok = function () {
$('#main_flash_alert').hide();
$('#main_info').show();
$('#main_tips').show();
$('#video_player').show();
//$('#btn_play').show();
};
var apply_url_change = function() {
var r = parse_rtmp_url($("#txt_url").val());
var url = window.location.protocol + "//" + query.host + query.pathname + "?autostart=true"
+ "&app=" + r.app + "&stream=" + r.stream + "&server=" + r.server + "&port=" + r.port;
url += (query.shp_identify) ? "&shp_identify=" + query.shp_identify : '';
url += (r.vhost === "__defaultVhost__") ? "&vhost=" + r.server : "&vhost=" + r.vhost;
url += (r.schema !== "rtmp") ? "&schema=" + r.schema : '';
url += (query.buffer) ? "&buffer=" + query.buffer : '';
url += (query.api_port) ? "&api_port=" + query.api_port : '';
var queries = user_extra_params(query);
queries = user_extra_params(r, queries);
if (queries && queries.length) {
url += '&' + queries.join('&');
}
$("#player_url").text($("#txt_url").val()).attr("href", url);
$("#link_url").attr("href", url);
// For RTMP, not support.
if (r.schema === 'rtmp') {
hide_for_error();
return;
}
return r;
};
var start_play = function (r) {
stopPlayers();
if (!r) return;
// Use H5 native to play mp4.
if (r.stream.indexOf('.mp4') > 0) {
$('#video_player').attr('src', r.url).show();
return;
}
// Start play HTTP-TS.
if (r.stream.indexOf('.ts') > 0) {
if (!mpegts.getFeatureList().mseLivePlayback) {
hide_for_error();
return;
}
show_for_ok();
tsPlayer = mpegts.createPlayer({type: 'mpegts', url: r.url, isLive: true, enableStashBuffer: false});
tsPlayer.attachMediaElement(document.getElementById('video_player'));
tsPlayer.load();
tsPlayer.play();
return;
}
// Start play HLS.
if (r.stream.indexOf('.m3u8') > 0) {
if (!Hls.isSupported()) {
hide_for_error();
return;
}
show_for_ok();
hlsPlayer = new Hls();
hlsPlayer.loadSource(r.url);
hlsPlayer.attachMedia(document.getElementById('video_player'));
return;
}
// Start play MPEG-DASH.
if (r.stream.indexOf('.mpd') > 0) {
show_for_ok();
dashPlayer = dashjs.MediaPlayer().create();
dashPlayer.initialize(document.querySelector("#video_player"), r.url, true);
return;
}
// Start play HTTP-FLV.
let isFlv = r.stream.indexOf('.flv') > 0;
// Compatible with NGINX-HTTP-FLV module, see https://github.com/winshining/nginx-http-flv-module and the stream
// url without .flv, such as:
// http://localhost:8080/live?app=live&stream=livestream
isFlv = isFlv || r.stream && r.url.indexOf('http') === 0;
if (isFlv) {
if (!mpegts.getFeatureList().mseLivePlayback) {
hide_for_error();
return;
}
show_for_ok();
flvPlayer = mpegts.createPlayer({type: 'flv', url: r.url, isLive: true, enableStashBuffer: false});
flvPlayer.attachMediaElement(document.getElementById('video_player'));
flvPlayer.load();
flvPlayer.play();
return;
}
Log an error message to the console stating "Unsupported URL", followed by the URL in question and the associated request object 'r'.
$('#video_player').hide();
};
$("#txt_url").change(function(){
apply_url_change();
});
$("#btn_play").click(function(){
$('#video_player').prop('muted', false);
var r = apply_url_change();
start_play(r);
});
/****
* The parameters for this page:
* schema, the protocol schema, rtmp or http.
* server, the ip of the url.
* port, the rtmp port of url.
* vhost, the vhost of url, can equals to server.
* app, the app of url.
* stream, the stream of url, can endwith .flv or .mp4 or nothing for RTMP.
* autostart, whether auto play the stream.
* buffer, the buffer time in seconds.
* extra params:
* shp_identify, hls+ param.
* for example:
* http://localhost:8088/players/srs_player.html?vhost=ossrs.net&app=live&stream=livestream&server=ossrs.net&port=1935&autostart=true&schema=rtmp
* http://localhost:8088/players/srs_player.html?vhost=ossrs.net&app=live&stream=livestream.flv&server=ossrs.net&port=8080&autostart=true&schema=http
*/
var query = parse_query_string();
// get the vhost and port to set the default url.
// url set to: http://localhost:8080/live/livestream.flv
srs_init_flv("#txt_url");
if (query.autostart === "true") {
$('#video_player').prop('muted', true);
console.warn('For autostart, we should mute it, see https://www.jianshu.com/p/c3c6944eed5a ' +
'or https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#audiovideo_elements');
var r = apply_url_change();
start_play(r);
} else {
$('#video_player').hide();
}
</script>
</html>
I created a configmap from the nginx.conf :
(base) raphy@raohy:~/.talos/nginx$ kubectl create configmap confnginx --from-file=conf/nginx.conf
configmap/confnginx created
(base) raphy@raohy:~/.talos/nginx$
(base) raphy@raohy:~/.talos/nginx$ kubectl get configmap
NAME DATA AGE
confnginx 1 14s
ingress-nginx-controller 0 3d20h
kube-root-ca.crt 1 200d
kube-starrocks-be-cm 1 48d
kube-starrocks-fe-cm 1 48d
kube-starrocks-fe-proxy 1 48d
kube-starrocks-initpwd-shell 1 48d
livekit-server 1 3d2h
nats-config 1 199d
redis-config 1 3d2h
(base) raphy@raohy:~/.talos/nginx$
(base) raphy@raohy:~/.talos/nginx$ kubectl describe configmap confnginx
Name: confnginx
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
nginx.conf:
----
# https://github.com/ossrs/srs/blob/develop/trunk/conf/https.rtc.conf
# https://stackoverflow.com/questions/42078080/add-nginx-conf-to-kubernetes-cluster
listen 1935;
max_connections 1000;
daemon off;
srs_log_tank console;
http_server {
server_name srs.myserver.name;
enabled on;
listen 8080;
dir ./srs_player.html;
https {
enabled on;
listen 8088;
key ./conf/server.key;
cert ./conf/server.crt;
}
}
http_api {
enabled on;
listen 1985;
https {
enabled on;
listen 1990;
key ./conf/server.key;
cert ./conf/server.crt;
}
}
stats {
network 0;
}
rtc_server {
enabled on;
listen 8000; # UDP port
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
candidate $CANDIDATE;
}
vhost __defaultVhost__ {
rtc {
enabled on;
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
rtmp_to_rtc off;
# @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
rtc_to_rtmp off;
}
http_remux {
enabled on;
mount [vhost]/[app]/[stream].flv;
}
}
BinaryData
====
Events: <none>
And created a deployment based on this configmap :
(base) raphy@raohy:~/.talos/nginx$ cat nginx.yaml
# https://stackoverflow.com/questions/42078080/add-nginx-conf-to-kubernetes-cluster
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /conf/nginx.conf
subPath: nginx.conf
volumes:
- name: nginx-config
configMap:
name: confnginx
(base) raphy@raohy:~/.talos/nginx$
(base) raphy@raohy:~/.talos/nginx$ kubectl apply -f nginx.yaml
deployment.apps/nginx created
(base) raphy@raohy:~/.talos/nginx$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
ingress-nginx-controller 1/1 1 1 3d20h
kube-starrocks-fe-proxy 1/1 1 1 48d
kube-starrocks-operator 1/1 1 1 48d
livekit-server 1/1 1 1 3d2h
lk-react 1/1 1 1 3d2h
nats-box 1/1 1 1 199d
nexus 1/1 1 1 2d4h
nginx 1/1 1 1 7s
srs-srs-server 1/1 1 1 7d22h
(base) raphy@raohy:~/.talos/nginx$ kubectl describe deployment nginx
Name: nginx
Namespace: default
CreationTimestamp: Sat, 19 Apr 2025 17:16:09 +0200
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=nginx
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:alpine
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts:
/conf/nginx.conf from nginx-config (rw,path="nginx.conf")
Volumes:
nginx-config:
Type: ConfigMap (a volume populated by a ConfigMap)
Name: confnginx
Optional: false
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-84d49776ff (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 19s deployment-controller Scaled up replica set nginx-84d49776ff to 1
But putting:
http://srs.myserver.name:8080/live/livestream.flv in the Live Player
does not work
Wha am I missing and / or doing wrong?
How to make it work?
TRANS_BY_GPT4