Git Product home page Git Product logo

whitphx / streamlit-webrtc Goto Github PK

View Code? Open in Web Editor NEW
1.2K 13.0 162.0 27.9 MB

Real-time video and audio streams over the network, with Streamlit.

Home Page: https://discuss.streamlit.io/t/new-component-streamlit-webrtc-a-new-way-to-deal-with-real-time-media-streams/8669

License: MIT License

Python 73.34% Shell 0.42% HTML 0.39% TypeScript 24.86% JavaScript 0.51% Makefile 0.34% Dockerfile 0.13%
streamlit streamlit-webrtc pypi webrtc video-streaming video-processing python hacktoberfest computer-vision

streamlit-webrtc's Introduction

streamlit-webrtc

Handling and transmitting real-time video/audio streams over the network with Streamlit Open in Streamlit

Tests Frontend Tests Ruff

PyPI PyPI - Python Version PyPI - License PyPI - Downloads

Sister project: streamlit-fesion to execute video filters on browsers with Wasm.

Examples

  • Object detection
  • OpenCV filter
  • Uni-directional video streaming
  • Audio processing

It converts your voice into text in real time. This app is self-contained; it does not depend on any external API.

It applies a wide variety of style transfer filters to real-time video streams.

(Online demo not available)

You can create video chat apps with ~100 lines of Python code.

MediaPipe is used for pose estimation.

Install

$ pip install -U streamlit-webrtc

Quick tutorial

See also the sample pages, pages/*.py, which contain a wide variety of usage.

See also "Developing Web-Based Real-Time Video/Audio Processing Apps Quickly with Streamlit".


Create app.py with the content below.

from streamlit_webrtc import webrtc_streamer

webrtc_streamer(key="sample")

Unlike other Streamlit components, webrtc_streamer() requires the key argument as a unique identifier. Set an arbitrary string to it.

Then run it with Streamlit and open http://localhost:8501/.

$ streamlit run app.py

You see the app view, so click the "START" button.

Then, video and audio streaming starts. If asked for permissions to access the camera and microphone, allow it. Basic example of streamlit-webrtc

Next, edit app.py as below and run it again.

from streamlit_webrtc import webrtc_streamer
import av


def video_frame_callback(frame):
    img = frame.to_ndarray(format="bgr24")

    flipped = img[::-1,:,:]

    return av.VideoFrame.from_ndarray(flipped, format="bgr24")


webrtc_streamer(key="example", video_frame_callback=video_frame_callback)

Now the video is vertically flipped. Vertically flipping example

As an example above, you can edit the video frames by defining a callback that receives and returns a frame and passing it to the video_frame_callback argument (or audio_frame_callback for audio manipulation). The input and output frames are the instance of av.VideoFrame (or av.AudioFrame when dealing with audio) of PyAV library.

You can inject any kinds of image (or audio) processing inside the callback. See examples above for more applications.

Pass parameters to the callback

You can also pass parameters to the callback.

In the example below, a boolean flip flag is used to turn on/off the image flipping.

import streamlit as st
from streamlit_webrtc import webrtc_streamer
import av


flip = st.checkbox("Flip")


def video_frame_callback(frame):
    img = frame.to_ndarray(format="bgr24")

    flipped = img[::-1,:,:] if flip else img

    return av.VideoFrame.from_ndarray(flipped, format="bgr24")


webrtc_streamer(key="example", video_frame_callback=video_frame_callback)

Pull values from the callback

Sometimes we want to read the values generated in the callback from the outer scope.

Note that the callback is executed in a forked thread running independently of the main script, so we have to take care of the following points and need some tricks for implementation like the example below (See also the section below for some limitations in the callback due to multi-threading).

  • Thread-safety
    • Passing the values between inside and outside the callback must be thread-safe.
  • Using a loop to poll the values
    • During media streaming, while the callback continues to be called, the main script execution stops at the bottom as usual. So we need to use a loop to keep the main script running and get the values from the callback in the outer scope.

The following example is to pass the image frames from the callback to the outer scope and continuously process it in the loop. In this example, a simple image analysis (calculating the histogram like this OpenCV tutorial) is done on the image frames.

threading.Lock is one standard way to control variable accesses across threads. A dict object img_container here is a mutable container shared by the callback and the outer scope and the lock object is used at assigning and reading the values to/from the container for thread-safety.

import threading

import cv2
import streamlit as st
from matplotlib import pyplot as plt

from streamlit_webrtc import webrtc_streamer

lock = threading.Lock()
img_container = {"img": None}


def video_frame_callback(frame):
    img = frame.to_ndarray(format="bgr24")
    with lock:
        img_container["img"] = img

    return frame


ctx = webrtc_streamer(key="example", video_frame_callback=video_frame_callback)

fig_place = st.empty()
fig, ax = plt.subplots(1, 1)

while ctx.state.playing:
    with lock:
        img = img_container["img"]
    if img is None:
        continue
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ax.cla()
    ax.hist(gray.ravel(), 256, [0, 256])
    fig_place.pyplot(fig)

Callback limitations

The callbacks are executed in forked threads different from the main one, so there are some limitations:

  • Streamlit methods (st.* such as st.write()) do not work inside the callbacks.
  • Variables inside the callbacks cannot be directly referred to from the outside.
  • The global keyword does not work expectedly in the callbacks.
  • You have to care about thread-safety when accessing the same objects both from outside and inside the callbacks as stated in the section above.

Class-based callbacks

Until v0.37, the class-based callbacks were the standard. See the old version of the README about it.

Serving from remote host

When deploying apps to remote servers, there are some things you need to be aware of. In short,

  • HTTPS is required to access local media devices.
  • STUN/TURN servers are required to establish the media stream connection.

See the following sections.

HTTPS

streamlit-webrtc uses getUserMedia() API to access local media devices, and this method does not work in an insecure context.

This document says

A secure context is, in short, a page loaded using HTTPS or the file:/// URL scheme, or a page loaded from localhost.

So, when hosting your app on a remote server, it must be served via HTTPS if your app is using webcam or microphone. If not, you will encounter an error when starting using the device. For example, it's something like below on Chrome.

Error: navigator.mediaDevices is undefined. It seems the current document is not loaded securely.

Streamlit Community Cloud is a recommended way for HTTPS serving. You can easily deploy Streamlit apps with it, and most importantly for this topic, it serves the apps via HTTPS automatically by default.

For the development purpose, sometimes suyashkumar/ssl-proxy is a convenient tool to serve your app via HTTPS.

$ streamlit run your_app.py  # Assume your app is running on http://localhost:8501
# Then, after downloading the binary from the GitHub page above to ./ssl-proxy,
$ ./ssl-proxy -from 0.0.0.0:8000 -to 127.0.0.1:8501  # Proxy the HTTP page from port 8501 to port 8000 via HTTPS
# Then access https://localhost:8000

Configure the STUN server

To deploy the app to the cloud, we have to configure the STUN server via the rtc_configuration argument on webrtc_streamer() like below.

webrtc_streamer(
    # ...
    rtc_configuration={  # Add this config
        "iceServers": [{"urls": ["stun:stun.l.google.com:19302"]}]
    }
    # ...
)

This configuration is necessary to establish the media streaming connection when the server is on a remote host.

⚠️ You may need to set up a TURN server as well in some environments, including Streamlit Community Cloud. See also the next section.

streamlit_webrtc uses WebRTC for its video and audio streaming. It has to access a "STUN server" in the global network for the remote peers (precisely, peers over the NATs) to establish WebRTC connections. As we don't see the details about STUN servers here, please google it if interested with keywords such as STUN, TURN, or NAT traversal, or read these articles (1, 2, 3).

The example above is configured to use stun.l.google.com:19302, which is a free STUN server provided by Google.

You can also use any other STUN servers. For example, one user reported that the Google's STUN server had a huge delay when using from China network, and the problem was solved by changing the STUN server.

For those who know about the browser WebRTC API: The value of the rtc_configuration argument will be passed to the RTCPeerConnection constructor on the frontend.

Configure the TURN server if necessary

Even if the STUN server is properly configured, media streaming may not work in some network environments, either from the server or from the client. For example, if the server is hosted behind a proxy, or if the client is on an office network behind a firewall, the WebRTC packets may be blocked (Streamlit Community Cloud is the case). This article summarizes the possible situations.

In such environments, TURN server is required.

There are several options for setting up a TURN server:

  • Twilio Network Traversal Service (recommended) is a stable and easy-to-use solution. It's a paid service, but you can start with a free trial with a certain amount of credit. You can simply pass the ice_servers field of the Network Traversal Service Tokens API response to the iceServers field of the rtc_configuration argument of webrtc_streamer().
    ## This sample code is from https://www.twilio.com/docs/stun-turn/api
    # Download the helper library from https://www.twilio.com/docs/python/install
    import os
    from twilio.rest import Client
    
    # Find your Account SID and Auth Token at twilio.com/console
    # and set the environment variables. See http://twil.io/secure
    account_sid = os.environ['TWILIO_ACCOUNT_SID']
    auth_token = os.environ['TWILIO_AUTH_TOKEN']
    client = Client(account_sid, auth_token)
    
    token = client.tokens.create()
    
    # Then, pass the ICE server information to webrtc_streamer().
    webrtc_streamer(
      # ...
      rtc_configuration={
          "iceServers": token.ice_servers
      }
      # ...
    )
    The WebRTC sample app hosted on the Community Cloud uses this option. See how it retrieves the ICE server information from the Twilio API and how to use it in the app.
  • The Open Relay Project provides a free TURN server. However, it does not seem to be stable enough and is often down.
  • A self-hosted TURN server is also an option. See #335 (comment).

Logging

For logging, this library uses the standard logging module and follows the practice described in the official logging tutorial. Then the logger names are the same as the module names - streamlit_webrtc or streamlit_webrtc.*.

So you can get the logger instance with logging.getLogger("streamlit_webrtc") through which you can control the logs from this library.

For example, if you want to set the log level on this library's logger as WARNING, you can use the following code.

st_webrtc_logger = logging.getLogger("streamlit_webrtc")
st_webrtc_logger.setLevel(logging.WARNING)

In practice, aiortc, a third-party package this library is internally using, also emits many INFO level logs and you may want to control its logs too. You can do it in the same way as below.

aioice_logger = logging.getLogger("aioice")
aioice_logger.setLevel(logging.WARNING)

API changes

Currently there is no documentation about the interface. See the examples in ./pages/*.py for the usage. The API is not finalized yet and can be changed without backward compatibility in the future releases until v1.0.

For users since versions <0.20

VideoTransformerBase and its transform method have been marked as deprecated in v0.20.0. Please use VideoProcessorBase#recv() instead. Note that the signature of the recv method is different from the transform in that the recv has to return an instance of av.VideoFrame or av.AudioFrame.

Also, webrtc_streamer()'s video_transformer_factory and async_transform arguments are deprecated, so use video_processor_factory and async_processing respectively.

See the samples in app.py for their usage.

Resources

Support the project

ko-fi

Buy Me A Coffee

GitHub Sponsors

streamlit-webrtc's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar tkoyama010 avatar whitphx avatar ya0guang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

streamlit-webrtc's Issues

AttributeError: 'str' object has no attribute 'get'

When launching the DeepSpeech demo I get this error.

image

Here is the full error:

File "/Users/alleon_g/.pyenv/versions/3.8.6/envs/lewagon/lib/python3.8/site-packages/streamlit/script_runner.py", line 349, in _run_script
    exec(code, module.__dict__)
File "/Users/alleon_g/code/galleon/refactored-octo-tribble/app.py", line 303, in <module>
    main()
File "/Users/alleon_g/code/galleon/refactored-octo-tribble/app.py", line 111, in main
    app_sst_with_video(
File "/Users/alleon_g/code/galleon/refactored-octo-tribble/app.py", line 212, in app_sst_with_video
    webrtc_ctx = webrtc_streamer(
File "/Users/alleon_g/.pyenv/versions/3.8.6/envs/lewagon/lib/python3.8/site-packages/streamlit_webrtc/__init__.py", line 289, in webrtc_streamer
    playing = component_value.get("playing", False)

Problem with SessionState

When I use SessionState in my streamlit, I getting this error

image

It can be solved by updating streamlit-webrtc SessionState.py file to

from streamlit.report_thread import get_report_ctx
import streamlit as st


class SessionState(object):
    def __init__(self, **kwargs):
        """A new SessionState object.

        Parameters
        ----------
        **kwargs : any
            Default values for the session state.

        Example
        -------
        >>> session_state = SessionState(user_name='', favorite_color='black')
        >>> session_state.user_name = 'Mary'
        ''
        >>> session_state.favorite_color
        'black'

        """
        for key, val in kwargs.items():
            setattr(self, key, val)


@st.cache(allow_output_mutation=True)
def get_session(id, **kwargs):
    return SessionState(**kwargs)


def get(**kwargs):
    """Gets a SessionState object for the current session.

    Creates a new object if necessary.

    Parameters
    ----------
    **kwargs : any
        Default values you want to add to the session state, if we're creating a
        new one.

    Example
    -------
    >>> session_state = get(user_name='', favorite_color='black')
    >>> session_state.user_name
    ''
    >>> session_state.user_name = 'Mary'
    >>> session_state.favorite_color
    'black'

    Since you set user_name above, next time your script runs this will be the
    result:
    >>> session_state = get(user_name='', favorite_color='black')
    >>> session_state.user_name
    'Mary'

    """
    ctx = get_report_ctx()
    id = ctx.session_id
    return get_session(id, **kwargs)

Credits: https://gist.github.com/tvst/036da038ab3e999a64497f42de966a92#gistcomment-3484515

Removing controls

Thanks for this great component !
I am trying to implement in streamlit an authentication using the webcam.
I was wondering if it was possible to get rid of the controls below:

image

Running deep learning models using a variety of media sources

Hi @whitphx
Thank you for your great work! streamlit-webrtc 😀

I want to run my custom deep learning models using a variety of media sources
For example, I want to run my YOLO model using the RTSP camera.

By modifying this function, I did run the model I trained
However, I could not use other media sources. It worked only on Webcam
I don't know how to change it to another media source.

Could you explain that function(app_object_detection()) with an example?
What should I change within this function

I wish you could help me.
Thank you.

Adjusting Size of Webcam Video

Hi @whitphx , first and foremost, thanks for this amazing component of Streamlit and your contributions. I would like to ask if there is a way to adjust the webcam video sizes after clicking "start"? As I switched into a large monitor and the video size seems to have quadrupled. I appreciate your feedback on this. Thanks

Regards and thanks.

Problem with RECVONLY reconnections

Hi, when I stop and start video files/streams, using RECVONLY, it doesn't work. It starts the video correctly, but when I stop and start again, it shows only a gray screen.

The log is:

2021-05-17 12:27:14.093 ICE connection state is closed
2021-05-17 12:27:15.780 Connection(42) Remote candidate "0163614b-42ff-4b75-925c-80a5e26dddb6.local" resolved to 192.168.1.13
2021-05-17 12:27:15.986 Connection(42) Check CandidatePair(('192.168.1.13', 56258) -> ('192.168.1.13', 59948)) State.FROZEN -> State.WAITING
2021-05-17 12:27:15.986 Connection(42) Check CandidatePair(('172.17.0.1', 60268) -> ('192.168.1.13', 59948)) State.FROZEN -> State.WAITING
2021-05-17 12:27:15.987 ICE connection state is checking
2021-05-17 12:27:15.987 Connection(42) Check CandidatePair(('192.168.1.13', 56258) -> ('192.168.1.13', 59948)) State.WAITING -> State.IN_PROGRESS
2021-05-17 12:27:16.028 Connection(42) Check CandidatePair(('172.17.0.1', 60268) -> ('192.168.1.13', 59948)) State.WAITING -> State.IN_PROGRESS
2021-05-17 12:27:16.031 Connection(42) Check CandidatePair(('192.168.1.13', 56258) -> ('192.168.1.13', 59948)) State.IN_PROGRESS -> State.SUCCEEDED
2021-05-17 12:27:16.032 Connection(42) Check CandidatePair(('172.17.0.1', 60268) -> ('192.168.1.13', 59948)) State.IN_PROGRESS -> State.SUCCEEDED

image

How can I solve it?

Connection(0) Remote candidate "xxxxxxxxxx.local" could not be resolved

Hi! Im trying to use your library for real time video streaming with streamlint. I'm facing an error with Ice Servers connection that I can't resolve. Could you please help me?

Code:

    media_file_info = {
        'local_file_path':tfile.name,
        'type':'video'
    }
    
    WEBRTC_CLIENT_SETTINGS = ClientSettings()
    WEBRTC_CLIENT_SETTINGS.update(
        {
            "media_stream_constraints": {
                "video": media_file_info["type"] == "video",
                "audio": media_file_info["type"] == "audio",
            }
        }
    )
    frame_rate = 30
    WEBRTC_CLIENT_SETTINGS.update(
        ClientSettings(
            media_stream_constraints={
                "video": {"frameRate": {"ideal": frame_rate}},
            },
        )
    )
    webrtc_ctx = webrtc_streamer(
        key="media-streaming",
        mode=WebRtcMode.RECVONLY,
        client_settings=WEBRTC_CLIENT_SETTINGS,
        player_factory=create_player,
        video_processor_factory=OpenCVVideoProcessor,
    )

    tfile.close()
    os.unlink(tfile.name)

Error:
image

Access rear camera of mobile phone

Thanks for the amazing tool but my question is, is it possible to access rear camera of mobile phone from streamlit-webrtc or does it give the choice between front and rear camera for example when we launch a real time streamlit web app on mobile phone.
Thanks,

Sendrecv streamer serves only one request at a time on a remote server

I have a streamer in sendrecv mode deployed on Google's App Engine.
The issue I'm facing is that when a visitor starts the stream it kinda clogs the instance, and the consequence is that only one visitor at a time can use the streamer. What is the reason, and is there a work-around? Thank you.

Implementation

WEBRTC_CLIENT_SETTINGS = ClientSettings(
    rtc_configuration={"iceServers": [{"urls": ["stun:stun.l.google.com:19302"]}]},
    media_stream_constraints={"video": True, "audio": False},
)
def app_mask_detection():

    class OpenCVVideoTransformer(VideoTransformerBase):
        def __init__(self) -> None:
            self.assembly = ModelAssembly()    

        def transform(self, frame: av.VideoFrame) -> av.VideoFrame:
            img = frame.to_ndarray(format="bgr24")
           
            return self.assembly.forwardFrame(img)

    webrtc_ctx = webrtc_streamer(
        key="opencv-filter",
        mode=WebRtcMode.SENDRECV,
        client_settings=WEBRTC_CLIENT_SETTINGS,
        video_transformer_factory=OpenCVVideoTransformer,
        async_transform=True,
    )

How to configure HTTPS in EC2 server

I would like to deploy this app into the AWS server but the application requires HTTPS protocol to stream video. How to configure HTTPS in streamlit application. by default, it takes HTTP protocol.

Audio recorder is slow when initialization

I run the example :
WebRTC is sendonly and audio frames are visualized with matplotlib (sendonly)
when I pressed the Start button , record device seems to initialize for a long time
image
after around 40 seconds, then show the graph
image

below is log message
~$ streamlit run https://raw.githubusercontent.com/whitphx/streamlit-webrtc-example/main/app.py

You can now view your Streamlit app in your browser.

Network URL: http://172.28.53.133:8501
External URL: http://114.32.244.17:8501

[2021-07-01 15:39:10,548] WARNING from main in /tmp/tmpvsih9xwf/app.py:672: AudioReciver is not set. Abort.
[2021-07-01 15:39:54,641] DEBUG from streamlit_webrtc in /home/gary/work/mypy3/lib/python3.8/site-packages/streamlit_webrtc/init.py:311: No worker exists though the offer SDP is set. Create a new worker (key="sendonly-audio").
[2021-07-01 15:39:54,657] DEBUG from streamlit_webrtc.webrtc in /home/gary/work/mypy3/lib/python3.8/site-packages/streamlit_webrtc/webrtc.py:381: _webrtc_thread_impl starts
[2021-07-01 15:39:54,662] INFO from streamlit_webrtc.webrtc in /home/gary/work/mypy3/lib/python3.8/site-packages/streamlit_webrtc/webrtc.py:176: Track audio received
[2021-07-01 15:39:54,662] INFO from streamlit_webrtc.webrtc in /home/gary/work/mypy3/lib/python3.8/site-packages/streamlit_webrtc/webrtc.py:180: Add a track <aiortc.rtcrtpreceiver.RemoteStreamTrack object at 0x7fcc958864f0> to receiver <streamlit_webrtc.receive.MediaReceiver object at 0x7fcc95866c70>
[2021-07-01 15:39:54,662] INFO from streamlit_webrtc.webrtc in /home/gary/work/mypy3/lib/python3.8/site-packages/streamlit_webrtc/webrtc.py:176: Track video received
[2021-07-01 15:39:54,662] INFO from streamlit_webrtc.webrtc in /home/gary/work/mypy3/lib/python3.8/site-packages/streamlit_webrtc/webrtc.py:186: Add a track <aiortc.rtcrtpreceiver.RemoteStreamTrack object at 0x7fcc95835f40> to receiver <streamlit_webrtc.receive.MediaReceiver object at 0x7fcc95866a90>
[2021-07-01 15:39:54,675] INFO from aioice.ice in /home/gary/work/mypy3/lib/python3.8/site-packages/aioice/ice.py:1061: Connection(0) Check CandidatePair(('172.28.53.133', 52580) -> ('172.28.48.1', 59954)) State.FROZEN -> State.WAITING
[2021-07-01 15:39:54,675] INFO from aioice.ice in /home/gary/work/mypy3/lib/python3.8/site-packages/aioice/ice.py:1061: Connection(0) Check CandidatePair(('172.28.53.133', 52580) -> ('10.0.0.3', 59955)) State.FROZEN -> State.WAITING
[2021-07-01 15:39:54,718] INFO from streamlit_webrtc.webrtc in /home/gary/work/mypy3/lib/python3.8/site-packages/streamlit_webrtc/webrtc.py:91: ICE connection state is checking
[2021-07-01 15:39:54,990] INFO from aioice.ice in /home/gary/work/mypy3/lib/python3.8/site-packages/aioice/ice.py:1061: Connection(0) Check CandidatePair(('172.28.53.133', 52580) -> ('172.28.48.1', 59954)) State.WAITING -> State.IN_PROGRESS
[2021-07-01 15:39:54,992] INFO from aioice.ice in /home/gary/work/mypy3/lib/python3.8/site-packages/aioice/ice.py:1061: Connection(0) Check CandidatePair(('172.28.53.133', 52580) -> ('10.0.0.3', 59955)) State.WAITING -> State.IN_PROGRESS
[2021-07-01 15:39:55,012] INFO from aioice.ice in /home/gary/work/mypy3/lib/python3.8/site-packages/aioice/ice.py:1061: Connection(0) Check CandidatePair(('172.28.53.133', 52580) -> ('192.168.137.1', 59956)) State.FROZEN -> State.IN_PROGRESS
[2021-07-01 15:39:55,033] INFO from aioice.ice in /home/gary/work/mypy3/lib/python3.8/site-packages/aioice/ice.py:1061: Connection(0) Check CandidatePair(('172.28.53.133', 52580) -> ('114.32.244.17', 59955)) State.FROZEN -> State.IN_PROGRESS
[2021-07-01 15:39:55,493] INFO from aioice.ice in /home/gary/work/mypy3/lib/python3.8/site-packages/aioice/ice.py:1061: Connection(0) Check CandidatePair(('172.28.53.133', 52580) -> ('172.28.48.1', 59954)) State.IN_PROGRESS -> State.SUCCEEDED
[2021-07-01 15:39:55,493] INFO from aioice.ice in /home/gary/work/mypy3/lib/python3.8/site-packages/aioice/ice.py:1061: Connection(0) ICE completed
[2021-07-01 15:39:55,501] INFO from streamlit_webrtc.webrtc in /home/gary/work/mypy3/lib/python3.8/site-packages/streamlit_webrtc/webrtc.py:91: ICE connection state is completed

Show emotion result in other window

Instead of showing all the responses in the frame, I want to show in separately. how to send all values in response and show it in the browser.

Issue about Video Recording

Hi @whitphx!
I met an issue when I call streamlit webrtc_streamer by using webrtc_streamer(key="example").

The device that I used is MacBook Pro with macOS Catalina. The browser that I have tested are Chrome, Safari and Firefox. After I clicked the "start" button, the webcamera would start with green light, but there is no video displayed on the webpage and the green light would disappear in second. The the message shown in the terminal like this:

2021-04-23 17:08:11.023 Track audio received 2021-04-23 17:08:11.023 Track video received 2021-04-23 17:08:11.566 Connection(0) Check CandidatePair(('172.17.0.82', 58866) -> ('172.17.0.82', 57933)) State.FROZEN -> State.WAITING 2021-04-23 17:08:11.567 Connection(0) Check CandidatePair(('192.168.43.10', 57659) -> ('172.17.0.82', 57933)) State.FROZEN -> State.WAITING 2021-04-23 17:08:11.568 Connection(0) Check CandidatePair(('172.17.0.82', 58866) -> ('192.168.43.10', 59518)) State.FROZEN -> State.WAITING 2021-04-23 17:08:11.569 ICE connection state is checking 2021-04-23 17:08:11.569 Connection(0) Check CandidatePair(('172.17.0.82', 58866) -> ('172.17.0.82', 57933)) State.WAITING -> State.IN_PROGRESS 2021-04-23 17:08:11.590 Connection(0) Check CandidatePair(('192.168.43.10', 57659) -> ('172.17.0.82', 57933)) State.WAITING -> State.IN_PROGRESS 2021-04-23 17:08:11.613 Connection(0) Check CandidatePair(('172.17.0.82', 58866) -> ('192.168.43.10', 59518)) State.WAITING -> State.IN_PROGRESS 2021-04-23 17:08:11.636 Connection(0) Check CandidatePair(('192.168.43.10', 57659) -> ('192.168.43.10', 59518)) State.FROZEN -> State.IN_PROGRESS 2021-04-23 17:09:15.083 Connection(0) Check CandidatePair(('172.17.0.82', 58866) -> ('172.17.0.82', 57933)) State.IN_PROGRESS -> State.FAILED 2021-04-23 17:09:15.103 Connection(0) Check CandidatePair(('192.168.43.10', 57659) -> ('172.17.0.82', 57933)) State.IN_PROGRESS -> State.FAILED 2021-04-23 17:09:15.121 Connection(0) Check CandidatePair(('172.17.0.82', 58866) -> ('192.168.43.10', 59518)) State.IN_PROGRESS -> State.FAILED 2021-04-23 17:09:15.153 Connection(0) Check CandidatePair(('192.168.43.10', 57659) -> ('192.168.43.10', 59518)) State.IN_PROGRESS -> State.FAILED 2021-04-23 17:09:15.153 Connection(0) ICE failed 2021-04-23 17:09:15.161 ICE connection state is failed 2021-04-23 17:09:15.161 ICE connection state is closed

Could you offer some help on this problem? Many thanks!

Experimenting streamlit-webrtc using Google Colab and Ngrok

Hi, anyone have been experimenting streamlit-webrtc component with Google Colabs and Ngrok, i need this setup because google colab have free gpu to serve my model.

I have an ICE connection state is failed after running app.py example,

https://gist.github.com/trisgelar/86968b75a3ff84f1425c1ccee6ad0415

Thanks.

You can now view your Streamlit app in your browser.

Network URL: http://172.28.0.2:8501
External URL: http://34.125.122.87:8501

2021-07-19 15:16:47.944 Restore the component value (key=object-detection)
2021-07-19 15:17:45.056 No worker exists though the offer SDP is set. Create a new worker (key="object-detection").
2021-07-19 15:17:45.073 _webrtc_thread_impl starts
2021-07-19 15:17:46.110 Connection(0) Remote candidate "47ce6f98-7967-4bee-af8b-3fba9e547390.local" could not be resolved
2021-07-19 15:17:46.110 Track audio received
2021-07-19 15:17:46.110 Add a track <aiortc.rtcrtpreceiver.RemoteStreamTrack object at 0x7fd7b9e60b10> of kind audio to <aiortc.rtcpeerconnection.RTCPeerConnection object at 0x7fd7d5325cd0>
2021-07-19 15:17:46.111 Track video received
2021-07-19 15:17:46.111 Set <aiortc.rtcrtpreceiver.RemoteStreamTrack object at 0x7fd7b8d32fd0> as an input video track with video_processor <class 'streamlit_webrtc.process.AsyncVideoProcessTrack'>
2021-07-19 15:17:46.111 Add a track <streamlit_webrtc.process.AsyncVideoProcessTrack object at 0x7fd7b8d37b90> of kind video to <aiortc.rtcpeerconnection.RTCPeerConnection object at 0x7fd7d5325cd0>
2021-07-19 15:17:46.149 Connection(0) Check CandidatePair(('172.28.0.2', 49728) -> ('120.89.90.198', 33875)) State.FROZEN -> State.WAITING
2021-07-19 15:17:46.197 ICE connection state is checking
2021-07-19 15:17:46.344 Connection(0) Check CandidatePair(('172.28.0.2', 49728) -> ('120.89.90.198', 33875)) State.WAITING -> State.IN_PROGRESS
2021-07-19 15:18:13.134 Unset the worker because the frontend state is neither playing nor signalling (key="object-detection").
2021-07-19 15:18:17.852 No worker exists though the offer SDP is set. Create a new worker (key="object-detection").
2021-07-19 15:18:17.853 _webrtc_thread_impl starts
2021-07-19 15:18:17.888 Track audio received
2021-07-19 15:18:17.888 Add a track <aiortc.rtcrtpreceiver.RemoteStreamTrack object at 0x7fd7d531a510> of kind audio to <aiortc.rtcpeerconnection.RTCPeerConnection object at 0x7fd7d8149a10>
2021-07-19 15:18:17.888 Track video received
2021-07-19 15:18:17.888 Set <aiortc.rtcrtpreceiver.RemoteStreamTrack object at 0x7fd7b8c0e410> as an input video track with video_processor <class 'streamlit_webrtc.process.AsyncVideoProcessTrack'>
2021-07-19 15:18:17.889 Add a track <streamlit_webrtc.process.AsyncVideoProcessTrack object at 0x7fd7b8c03090> of kind video to <aiortc.rtcpeerconnection.RTCPeerConnection object at 0x7fd7d8149a10>
2021-07-19 15:18:17.972 Connection(2) Check CandidatePair(('172.28.0.2', 53740) -> ('192.168.0.106', 39647)) State.FROZEN -> State.WAITING
2021-07-19 15:18:17.973 Connection(2) Check CandidatePair(('172.28.0.2', 53740) -> ('120.89.90.198', 39647)) State.FROZEN -> State.WAITING
2021-07-19 15:18:18.112 ICE connection state is checking
2021-07-19 15:18:18.112 Connection(2) Check CandidatePair(('172.28.0.2', 53740) -> ('192.168.0.106', 39647)) State.WAITING -> State.IN_PROGRESS
2021-07-19 15:18:18.189 Connection(2) Check CandidatePair(('172.28.0.2', 53740) -> ('120.89.90.198', 39647)) State.WAITING -> State.IN_PROGRESS
2021-07-19 15:18:49.853 Connection(0) Check CandidatePair(('172.28.0.2', 49728) -> ('120.89.90.198', 33875)) State.IN_PROGRESS -> State.FAILED
2021-07-19 15:18:49.853 Connection(0) ICE failed
2021-07-19 15:18:49.860 ICE connection state is failed
2021-07-19 15:18:49.860 ICE connection state is closed
2021-07-19 15:19:21.619 Connection(2) Check CandidatePair(('172.28.0.2', 53740) -> ('192.168.0.106', 39647)) State.IN_PROGRESS -> State.FAILED
2021-07-19 15:19:21.705 Connection(2) Check CandidatePair(('172.28.0.2', 53740) -> ('120.89.90.198', 39647)) State.IN_PROGRESS -> State.FAILED
2021-07-19 15:19:21.706 Connection(2) ICE failed
2021-07-19 15:19:21.720 ICE connection state is failed
2021-07-19 15:19:21.721 ICE connection state is closed

1 input to N outputs

For example, 1 input from a single camera, 2 outputs including a raw preview and a transformed stream.

🐞 : `NotImplementedError: transform() is not implemented`

Hi, first of thanks a lot for this module, really appreciate your hard work. I'm trying to reproduce the simple example given in your write up. Here's the code:

import cv2 as cv
from streamlit_webrtc import VideoTransformerBase, webrtc_streamer


class VideoTransformer(VideoTransformerBase):

    def capture(self, frame):
        img = frame.to_ndarray(format='bgr24')
        img = cv.cvtColor(cv.Canny(img, 100, 200), cv.COLOR_GRAY2BGR)
        return img


webrtc_streamer(key='Test', video_transformer_factory=VideoTransformer)

But I see no change:

image

However there's an error:

...
2021-05-24 18:42:11.462 Connection(0) ICE completed
2021-05-24 18:42:11.463 ICE connection state is completed
2021-05-24 18:42:11.565 transform() is deprecated. Implement recv() instead.
2021-05-24 18:42:11.565 Error occurred in the WebRTC thread:
2021-05-24 18:42:11.566 Traceback (most recent call last):
2021-05-24 18:42:11.566   File "/home/jovial/Dev/anaconda3/envs/vdk/lib/python3.8/site-packages/streamlit_webrtc/process.py", line 157, in _run_worker_thread
2021-05-24 18:42:11.566     self._worker_thread()
2021-05-24 18:42:11.566   File "/home/jovial/Dev/anaconda3/envs/vdk/lib/python3.8/site-packages/streamlit_webrtc/process.py", line 242, in _worker_thread
2021-05-24 18:42:11.566     new_frames = finished.result()
2021-05-24 18:42:11.566   File "/home/jovial/Dev/anaconda3/envs/vdk/lib/python3.8/site-packages/streamlit_webrtc/process.py", line 54, in recv_queued
2021-05-24 18:42:11.566     return [self.recv(frames[-1])]
2021-05-24 18:42:11.566   File "/home/jovial/Dev/anaconda3/envs/vdk/lib/python3.8/site-packages/streamlit_webrtc/process.py", line 45, in recv
2021-05-24 18:42:11.566     new_image = self.transform(frame)
2021-05-24 18:42:11.566   File "/home/jovial/Dev/anaconda3/envs/vdk/lib/python3.8/site-packages/streamlit_webrtc/process.py", line 33, in transform
2021-05-24 18:42:11.567     raise NotImplementedError("transform() is not implemented.")
2021-05-24 18:42:11.567 NotImplementedError: transform() is not implemented.
...

Am I doing something wrong?

Video is not being displayed

Hey @whitphx, I've tracked this repo from the forums. And when I'm trying to access the website for a project I'm working on, it is taking forever to display even the simple video loopback. So is this a problem from myside or is the site broken ?

Screenshot (269)

RuntimeError: There is no current event loop in thread 'ScriptRunner.scriptThread'.

File "/Users/whitphx/.pyenv/versions/3.8.6/envs/streamlit-dev/lib/python3.8/site-packages/streamlit/script_runner.py", line 332, in _run_script
    exec(code, module.__dict__)
File "/Users/whitphx/.ghq/github.com/whitphx/streamlit-webrtc/app.py", line 19, in <module>
    from aiortc.contrib.media import MediaPlayer
File "/Users/whitphx/.pyenv/versions/3.8.6/envs/streamlit-dev/lib/python3.8/site-packages/aiortc/__init__.py", line 8, in <module>
    from .rtcdtlstransport import (
File "/Users/whitphx/.pyenv/versions/3.8.6/envs/streamlit-dev/lib/python3.8/site-packages/aiortc/rtcdtlstransport.py", line 22, in <module>
    from .rtcicetransport import RTCIceTransport
File "/Users/whitphx/.pyenv/versions/3.8.6/envs/streamlit-dev/lib/python3.8/site-packages/aiortc/rtcicetransport.py", line 7, in <module>
    from aioice import Candidate, Connection
File "/Users/whitphx/.pyenv/versions/3.8.6/envs/streamlit-dev/lib/python3.8/site-packages/aioice/__init__.py", line 5, in <module>
    from .ice import Connection
File "/Users/whitphx/.pyenv/versions/3.8.6/envs/streamlit-dev/lib/python3.8/site-packages/aioice/ice.py", line 29, in <module>
    _mdns_lock = asyncio.Lock()
File "/Users/whitphx/.pyenv/versions/3.8.6/lib/python3.8/asyncio/locks.py", line 164, in __init__
    self._loop = events.get_event_loop()
File "/Users/whitphx/.pyenv/versions/3.8.6/lib/python3.8/asyncio/events.py", line 639, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'

It seems this error occurs with aiortc >= 1.1.0 (aioice >= 0.7.2).

  • Specify the exact version 1.0.0 as a dependency #38
  • Fix this problem with aiortc >= 1.1.0 (aioice >= 0.7.2) #71

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.