About using webrtc from non-SSL web screen

kazuki

New Member
Hello,

Please tell me about using webrtc from non-SSL web screen.

I'm trying to create a player for webrtc in a web app.

Since this web application is used within the LAN, it will be executed under HTTP.
(Example: http: // <ServerIP> /webrtc.html
web server uses apache)

As a test, I ported the demo "2players" html under apache.
Then I tried the following tests.

1. test1
When executed under HTTPS using a self-signed certificate,
player connected to wss and was able to watch with 2player without any problems.
(Caputure1)
_スクリーンショット 2020-11-25 18.24.48のコピー.png



2.test2
When executed under HTTP, regardless of whether player connect to wss (8443) or ws (8080)
I can watch it on one player, but when I try to play the second player, both freeze.
When I checked with chrome, the following error was displayed on the console screen
"Uncaught (in promise) typeerror: cannot set property'muted' of null"
(Caputure2)
_スクリーンショット 2020-11-25 18.28.09のコピー.png



-Server OS: Ubuntu 18.04.3 LTS
-WebCallServer: 5.2.838
-Checked web browser: chrome (mac), safari (mac), firefox (mac) all freeze

Here's a question.
Is it possible to display 2player with webrtc even from an HTTP web application?

The ported html is as follows.
Code:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://192.168.1.30:8444/client2/examples/demo/streaming/2players/2players.css">
    <title>Player</title>
    <script type="text/javascript" src="https://192.168.1.30:8444/client2/flashphoner.js"></script>
    <script type="text/javascript" src="https://192.168.1.30:8444/client2/examples/demo/dependencies/jquery/jquery-1.12.0.js"></script>
    <script type="text/javascript" src="https://192.168.1.30:8444/client2/examples/demo/dependencies/jquery/jquery-ui.js"></script>
    <script type="text/javascript" src="https://192.168.1.30:8444/client2/examples/demo/dependencies/js/utils.js"></script>

    <script type="text/javascript" src="https://192.168.1.30:8444/client2/examples/demo/streaming/2players/2players.js"></script>
    <!-- Bootstrap JS -->
    <script src="https://192.168.1.30:8444/client2/examples/demo/dependencies/bootstrap/js/bootstrap.js"></script>
</head>
<body onload="init_page()">
<div class="container">
    <div class="row">

        <h2 id="notifyFlash" class="text-danger"></h2>

        <div class="col-sm-9 text-center">

            <h2 class="text-center">2 players</h2>

            <div class="col-sm-6">
                <div class="text-center text-muted">Player 1</div>
                <div class="fp-remoteVideo">
                    <div id="player1" class="display"></div>
                </div>

                <div id="form1" class="input-group col-sm-10" style="margin: 10px auto 0 auto;">
                    <input class="form-control" type="text" id="streamName1" value="streamName1">
                    <div class="input-group-btn">
                        <button id="playBtn1" type="button" class="btn btn-default">Play</button>
                    </div>
                </div>
                <div class="text-center" style="margin-top: 20px">
                    <div id="status1"></div>
                </div>
            </div>

            <div class="col-sm-6">
                <div class="text-center text-muted">Player 2</div>
                <div class="fp-remoteVideo">
                    <div id="player2" class="display"></div>
                </div>
                <div id="form2" class="input-group col-sm-10" style="margin: 10px auto 0 auto;">
                    <input class="form-control" type="text" id="streamName2" value="streamName2">
                    <div class="input-group-btn">
                        <button id="playBtn2" type="button" class="btn btn-default">Play</button>
                    </div>
                </div>
                <div class="text-center" style="margin-top: 20px">
                    <div id="status2"></div>
                </div>
            </div>
        </div>
    </div>
    <div class="row row-space">
        <div class="col-sm-5 col-sm-offset-2">
            <div id="connectionForm" class="input-group">
                <input class="form-control" id="url" type="text">
                <div class="input-group-btn">
                    <button id="connectBtn" type="button" class="btn btn-default">Connect</button>
                </div>
            </div>
            <div class="text-center">
                <div id="connectStatus"></div>
            </div>
        </div>
    </div>
    <div class="row" style="margin-top: 70px;">
        <div class="col-sm-4">
            <a href="https://play.google.com/store/apps/details?id=com.flashphoner.wcsexample.twoplayers"><img src="../../dependencies/img/google_play.jpg" title="Google Play" alt="Google Play"></a>
        </div>
    </div>
</div>
</body>
</html>
Thank you
 
Last edited:

kazuki

New Member
Thank you, Max.

I confirmed the behavior on the demo site you taught me.

However, the result was the same for both chrome (mac, windows).
When I try to play the second player, it freezes.

This event does not reappear in your environment.

I'm using OBS for delivery, is this also the cause of the bad thing?

(WEB application cannot use HTTPS because I want to use obs-websocket ..)




_スクリーンショット 2020-11-26 9.55.24のコピー.png
 

Max

Administrator
Staff member
WebRTC does not work in browser via insecure connection (HTTP), it needs to be connected via HTTPS. Therefore, when you use HTTP, stream can be played using MSE or WSPlayer technologies. Both of them use websocket connection to transfer mediadata. So it is impossible to play two streams in one websocket session using MSE or WSPlayer.
The best approach is to use HTTPS and WebRTC, it requires SSL cerificate setup, but allows playback from mobile devices (especially iOS).
If, however, you prefer to use HTTP, you have to establish two websocket sessions to play two streams from one page. Let's tweak 2Players example (quick and dirty):
Code:
...
function connect() {
    var url = $('#url').val();
    // Create 1st session
    console.log("Create new session with url " + url);
    Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function(session){
        setStatus("#connectStatus", session.status());
        onConnected(session)
    }).on(SESSION_STATUS.DISCONNECTED, function(){
        setStatus("#connectStatus", SESSION_STATUS.DISCONNECTED);
        onDisconnected();
    }).on(SESSION_STATUS.FAILED, function(){
        setStatus("#connectStatus", SESSION_STATUS.FAILED);
        onDisconnected();
    });
    // Create 2nd session
    Flashphoner.createSession({urlServer: url}).on(SESSION_STATUS.ESTABLISHED, function(session){
        setStatus("#connectStatus", session.status());
        onConnected(session)
    }).on(SESSION_STATUS.DISCONNECTED, function(){
        setStatus("#connectStatus", SESSION_STATUS.DISCONNECTED);
        onDisconnected();
    }).on(SESSION_STATUS.FAILED, function(){
        setStatus("#connectStatus", SESSION_STATUS.FAILED);
        onDisconnected();
    });
}
...
function playStream(index, display) {
    // Get the session from list according to stream index
    var session = Flashphoner.getSessions()[index - 1];
    var streamName = $('#streamName' + index).val();
    // Play stream using this session
    session.createStream({
        name: streamName,
        display: display
    }).on(STREAM_STATUS.PENDING, function(stream) {
        var video = document.getElementById(stream.id());
        if (!video.hasListeners) {
            video.hasListeners = true;
            video.addEventListener('resize', function (event) {
                resizeVideo(event.target);
            });
        }
    }).on(STREAM_STATUS.PLAYING, function(stream) {
        setStatus("#status" + index, stream.status());
        onPlaying(index, stream);
    }).on(STREAM_STATUS.STOPPED, function() {
        setStatus("#status" + index, STREAM_STATUS.STOPPED);
        onStopped(index);
    }).on(STREAM_STATUS.FAILED, function() {
        setStatus("#status" + index, STREAM_STATUS.FAILED);
        onStopped(index);
    }).play();
}
...
(WEB application cannot use HTTPS because I want to use obs-websocket ..)
Please clarify: do you plan to use OBS WebRTC client to publish stream? If yes, then you must use HTTPS for playback because OBS WebRTC client publishes VP8 only, but MSE uses H.264, so stream will be transcoded on server. This is a CPU consumptive operation (at least one CPU core per 2 720p streams). You can play VP8 without transcoding via WebRTC only.
 

kazuki

New Member
Thank you for telling me the solution

As a result of various tests,
it worked in chrome.
(Both mac and windows)

However, it didn't work on iOS(iPad).
Is it possible to get 2player to work on iOS over HTTP?

In addition, when using iOS, the following log is displayed
19: 04: 30,422 INFO MediaSession --IceTimeoutThread --6fc5fc60-32f3-11eb-a341-e14ae89256ff Ice timeout thread interrupted


Also, the obs-websoket I want to use was:
I'm sorry for the confusing description.
This module doesn't seem to work over HTTPS when used within a LAN.
 
Last edited:

Max

Administrator
Staff member
It won't work production ready. You can see dirty workaround in the post above for MSE or WSPlayer https://forum.flashphoner.com/threads/about-using-webrtc-from-non-ssl-web-screen.13292/post-25626

Another way you can try to add two streams into the mixer (one stream).

REST API

Code:
/mixer/startup {}
/mixer/add {}
So if you have 1 mixed stream you play exactly 1 stream from http page and it should work on iOS Safari too.

Mixer docs

Mixer REST API
 

kazuki

New Member
Thank you for suggesting a countermeasure.

After negotiating with the customer, we decided to exclude viewing on iOS this time.
 
Top