How to Disable WebRTC in QWebEngineView with PyQt5

Control WebRTC settings and feature permissions in PyQt5's web engine
Heads up! You've already completed this tutorial.

PyQt5's QWebEngineView is built on top of Chromium, which means it comes with WebRTC support baked in. If you're building a browser-like application and want to restrict or disable WebRTC behavior, there are a couple of approaches you can take depending on what exactly you want to achieve.

Limiting WebRTC to Public Interfaces Only

Qt's QWebEngineSettings provides a setting called WebRTCPublicInterfacesOnly. When enabled, this restricts WebRTC so that it only exposes your public IP address, rather than leaking local/private network addresses. This is useful for privacy, though it doesn't fully disable WebRTC.

You can apply this setting to any QWebEngineView like so:

python
from PyQt5.QtWebEngineWidgets import QWebEngineSettings, QWebEngineView

webview = QWebEngineView()

webview.page().settings().setAttribute(
    QWebEngineSettings.WebRTCPublicInterfacesOnly, True
)

This is a one-liner that takes effect immediately for that page. It won't stop WebRTC entirely, but it will prevent it from revealing your private network interfaces.

Denying Feature Permission Requests

WebRTC typically requires access to the user's camera and/or microphone. In Chromium-based browsers, these are gated behind permission requests. In PyQt5, the QWebEnginePage emits a featurePermissionRequested signal whenever a website asks for access to features like audio or video capture.

By connecting to this signal and denying all media-related permissions, you can effectively prevent WebRTC audio/video from working — even though WebRTC itself is still technically present in the engine. If you're new to the concept of signals in Qt, see our tutorial on signals, slots and events.

Here's how that works:

python
from PyQt5.QtWebEngineWidgets import QWebEnginePage


def handle_permission_request(origin, feature):
    # Deny all media capture requests
    if feature in (
        QWebEnginePage.MediaAudioCapture,
        QWebEnginePage.MediaVideoCapture,
        QWebEnginePage.MediaAudioVideoCapture,
    ):
        webview.page().setFeaturePermission(
            origin, feature, QWebEnginePage.PermissionDeniedByUser
        )


webview.page().featurePermissionRequested.connect(handle_permission_request)

When a page tries to access the microphone or camera (as WebRTC calls typically do), your handler fires and immediately denies the request. The page receives a denial just as it would if a user clicked "Block" in a normal browser permission dialog.

1:1 Coaching & Tutoring for your Python GUIs project
Martin Fitzpatrick Python GUIs Coaching & Training
60 mins ($195) Book Now

1:1 Python GUIs Coaching & Training

Comprehensive code reviewBugfixes & improvements • Maintainability advice and architecture improvements • Design and usability assessment • Suggestions and tips to expand your knowledgePackaging and distribution help for Windows, Mac & Linux • Find out more.

Complete Working Example

Here's a full example that combines both approaches — limiting WebRTC to public interfaces and denying all media capture permissions:

python
import sys

from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import (
    QWebEnginePage,
    QWebEngineSettings,
    QWebEngineView,
)


class WebView(QWebEngineView):
    def __init__(self):
        super().__init__()

        # Restrict WebRTC to public interfaces only.
        self.page().settings().setAttribute(
            QWebEngineSettings.WebRTCPublicInterfacesOnly, True
        )

        # Deny camera/microphone permission requests.
        self.page().featurePermissionRequested.connect(
            self.handle_permission_request
        )

        self.setUrl(QUrl("https://webrtc.github.io/samples/"))

    def handle_permission_request(self, origin, feature):
        media_features = (
            QWebEnginePage.MediaAudioCapture,
            QWebEnginePage.MediaVideoCapture,
            QWebEnginePage.MediaAudioVideoCapture,
        )
        if feature in media_features:
            print(f"Denied media permission request from {origin.toString()}")
            self.page().setFeaturePermission(
                origin, feature, QWebEnginePage.PermissionDeniedByUser
            )


app = QApplication(sys.argv)

window = WebView()
window.setWindowTitle("WebRTC Restricted Browser")
window.resize(1024, 768)
window.show()

sys.exit(app.exec_())

Run this, and you'll see the WebRTC samples page load. If you try any of the demos that request camera or microphone access, the permission will be automatically denied and a message printed to your console.

Limitations

There is no built-in Qt setting to completely disable the WebRTC stack within the Chromium engine. The WebRTCPublicInterfacesOnly flag helps with IP leak concerns, and denying feature permissions blocks media capture, but WebRTC data channels and other non-media uses may still function. For most privacy-related use cases, combining both techniques above provides solid coverage.

If you need to pass Chromium command-line flags (for example --disable-webrtc), you can do so by setting them before creating your QApplication. For more on passing command-line arguments to Qt applications, see our FAQ on QApplication sys.argv and command line arguments:

python
import sys
sys.argv += ["--disable-webrtc"]

from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)

Whether this flag is respected depends on the version of Chromium bundled with your Qt installation, so test carefully if you go this route. Once your application is ready for distribution, you can package it with PyInstaller to share it with users.

Create GUI Applications with Python & Qt6 by Martin Fitzpatrick — (PyQt6 Edition) The hands-on guide to making apps with Python — Save time and build better with this book. Over 15K copies sold.

Get the book

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak
Martin Fitzpatrick

How to Disable WebRTC in QWebEngineView with PyQt5 was written by Martin Fitzpatrick.

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt. Martin founded PythonGUIs to provide easy to follow GUI programming tutorials to the Python community. He has written a number of popular Python books on the subject.