Showing preview only (2,043K chars total). Download the full file or copy to clipboard to get everything.
Repository: bluenviron/mediamtx
Branch: main
Commit: a82e0c7a9d52
Files: 473
Total size: 1.9 MB
Directory structure:
gitextract__vy29lq8/
├── .dockerignore
├── .github/
│ ├── DISCUSSION_TEMPLATE/
│ │ └── questions.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug.yml
│ │ ├── config.yml
│ │ └── feature.yml
│ ├── dependabot.yml
│ └── workflows/
│ ├── lint.yml
│ ├── nightly_binaries.yml
│ ├── release.yml
│ └── test.yml
├── .gitignore
├── .golangci.yml
├── LICENSE
├── Makefile
├── README.md
├── SECURITY.md
├── api/
│ ├── .redocly.yaml
│ └── openapi.yaml
├── docker/
│ ├── ffmpeg-rpi.Dockerfile
│ ├── ffmpeg.Dockerfile
│ ├── rpi.Dockerfile
│ └── standard.Dockerfile
├── docs/
│ ├── 1-kickoff/
│ │ ├── 1-introduction.md
│ │ ├── 2-install.md
│ │ ├── 3-upgrade.md
│ │ ├── 4-basic-usage.md
│ │ └── index.md
│ ├── 2-publish/
│ │ ├── 01-overview.md
│ │ ├── 02-srt-clients.md
│ │ ├── 03-srt-cameras-and-servers.md
│ │ ├── 04-webrtc-clients.md
│ │ ├── 05-webrtc-servers.md
│ │ ├── 06-rtsp-clients.md
│ │ ├── 07-rtsp-cameras-and-servers.md
│ │ ├── 08-rtmp-clients.md
│ │ ├── 09-rtmp-cameras-and-servers.md
│ │ ├── 10-hls-cameras-and-servers.md
│ │ ├── 11-mpeg-ts.md
│ │ ├── 12-rtp.md
│ │ ├── 13-raspberry-pi-cameras.md
│ │ ├── 14-generic-webcams.md
│ │ ├── 15-ffmpeg.md
│ │ ├── 16-gstreamer.md
│ │ ├── 17-obs-studio.md
│ │ ├── 18-python-opencv.md
│ │ ├── 19-golang.md
│ │ ├── 20-unity.md
│ │ ├── 21-web-browsers.md
│ │ └── index.md
│ ├── 3-read/
│ │ ├── 01-overview.md
│ │ ├── 02-srt.md
│ │ ├── 03-webrtc.md
│ │ ├── 04-rtsp.md
│ │ ├── 05-rtmp.md
│ │ ├── 06-hls.md
│ │ ├── 07-ffmpeg.md
│ │ ├── 08-gstreamer.md
│ │ ├── 09-vlc.md
│ │ ├── 10-obs-studio.md
│ │ ├── 11-python-opencv.md
│ │ ├── 12-golang.md
│ │ ├── 13-unity.md
│ │ ├── 14-web-browsers.md
│ │ └── index.md
│ ├── 4-other/
│ │ ├── 02-configuration.md
│ │ ├── 03-authentication.md
│ │ ├── 04-remuxing-reencoding-compression.md
│ │ ├── 05-always-available.md
│ │ ├── 06-record.md
│ │ ├── 07-playback.md
│ │ ├── 08-forward.md
│ │ ├── 09-proxy.md
│ │ ├── 10-extract-snapshots.md
│ │ ├── 11-on-demand-publishing.md
│ │ ├── 12-absolute-timestamps.md
│ │ ├── 13-expose-the-server-in-a-subfolder.md
│ │ ├── 14-embed-streams-in-a-website.md
│ │ ├── 15-start-on-boot.md
│ │ ├── 16-logging.md
│ │ ├── 17-hooks.md
│ │ ├── 18-control-api.md
│ │ ├── 19-metrics.md
│ │ ├── 20-performance.md
│ │ ├── 21-srt-specific-features.md
│ │ ├── 22-webrtc-specific-features.md
│ │ ├── 23-rtsp-specific-features.md
│ │ ├── 24-rtmp-specific-features.md
│ │ ├── 25-decrease-packet-loss.md
│ │ └── index.md
│ ├── 5-references/
│ │ ├── 1-configuration-file.md
│ │ ├── 2-control-api.md
│ │ └── index.md
│ ├── 6-misc/
│ │ ├── 1-compile.md
│ │ ├── 2-license.md
│ │ ├── 3-security.md
│ │ ├── 4-specifications.md
│ │ ├── 5-related-projects.md
│ │ └── index.md
│ └── redirects.yaml
├── go.mod
├── go.sum
├── internal/
│ ├── api/
│ │ ├── api.go
│ │ ├── api_config_global.go
│ │ ├── api_config_global_test.go
│ │ ├── api_config_pathdefaults.go
│ │ ├── api_config_pathdefaults_test.go
│ │ ├── api_config_paths.go
│ │ ├── api_config_paths_test.go
│ │ ├── api_hls.go
│ │ ├── api_hls_test.go
│ │ ├── api_paths.go
│ │ ├── api_paths_test.go
│ │ ├── api_recordings.go
│ │ ├── api_recordings_test.go
│ │ ├── api_rtmp.go
│ │ ├── api_rtmp_test.go
│ │ ├── api_rtsp.go
│ │ ├── api_rtsp_test.go
│ │ ├── api_srt.go
│ │ ├── api_srt_test.go
│ │ ├── api_test.go
│ │ ├── api_webrtc.go
│ │ ├── api_webrtc_test.go
│ │ ├── paginate.go
│ │ ├── paginate_test.go
│ │ └── testdata/
│ │ └── fuzz/
│ │ └── FuzzPaginate/
│ │ ├── 23731da0f18d31d0
│ │ ├── 34523a772174e26e
│ │ └── 85649d45641911d0
│ ├── auth/
│ │ ├── credentials.go
│ │ ├── error.go
│ │ ├── jwt_claims.go
│ │ ├── manager.go
│ │ ├── manager_test.go
│ │ └── request.go
│ ├── certloader/
│ │ ├── certloader.go
│ │ └── certloader_test.go
│ ├── conf/
│ │ ├── always_available_track.go
│ │ ├── always_available_track_codec.go
│ │ ├── auth_action.go
│ │ ├── auth_internal_user.go
│ │ ├── auth_internal_user_permission.go
│ │ ├── auth_method.go
│ │ ├── conf.go
│ │ ├── conf_test.go
│ │ ├── credential.go
│ │ ├── credential_test.go
│ │ ├── decrypt/
│ │ │ └── decrypt.go
│ │ ├── duration.go
│ │ ├── duration_test.go
│ │ ├── encryption.go
│ │ ├── env/
│ │ │ ├── env.go
│ │ │ └── env_test.go
│ │ ├── global.go
│ │ ├── hls_variant.go
│ │ ├── ip_network.go
│ │ ├── ip_networks.go
│ │ ├── jsonwrapper/
│ │ │ ├── testdata/
│ │ │ │ └── fuzz/
│ │ │ │ └── FuzzUnmarshal/
│ │ │ │ ├── 297c43aee5d30530
│ │ │ │ └── 7f71a2d116d5afde
│ │ │ ├── unmarshal.go
│ │ │ └── unmarshal_test.go
│ │ ├── log_destination.go
│ │ ├── log_destinations.go
│ │ ├── log_level.go
│ │ ├── optional_global.go
│ │ ├── optional_path.go
│ │ ├── path.go
│ │ ├── path_test.go
│ │ ├── record_format.go
│ │ ├── rtsp_auth_method.go
│ │ ├── rtsp_auth_methods.go
│ │ ├── rtsp_range_type.go
│ │ ├── rtsp_transport.go
│ │ ├── rtsp_transports.go
│ │ ├── string_size.go
│ │ ├── webrtc_ice_server.go
│ │ └── yamlwrapper/
│ │ ├── testdata/
│ │ │ └── fuzz/
│ │ │ └── FuzzUnmarshal/
│ │ │ ├── 90b5d1b18dd9f8ac
│ │ │ └── dc806ec658c460fc
│ │ ├── unmarshal.go
│ │ └── unmarshal_test.go
│ ├── confwatcher/
│ │ ├── confwatcher.go
│ │ └── confwatcher_test.go
│ ├── core/
│ │ ├── api_test.go
│ │ ├── core.go
│ │ ├── core_test.go
│ │ ├── metrics_test.go
│ │ ├── path.go
│ │ ├── path_manager.go
│ │ ├── path_manager_test.go
│ │ ├── path_test.go
│ │ ├── source_redirect.go
│ │ ├── test_on_demand/
│ │ │ └── main.go
│ │ ├── upgrade.go
│ │ ├── upgrade_disabled.go
│ │ └── versiongetter/
│ │ └── main.go
│ ├── counterdumper/
│ │ ├── dumper.go
│ │ └── dumper_test.go
│ ├── defs/
│ │ ├── api.go
│ │ ├── api_hls.go
│ │ ├── api_path.go
│ │ ├── api_path_track.go
│ │ ├── api_path_track_codec.go
│ │ ├── api_path_track_codec_props.go
│ │ ├── api_path_track_codec_test.go
│ │ ├── api_recording.go
│ │ ├── api_rtmp.go
│ │ ├── api_rtsp.go
│ │ ├── api_srt.go
│ │ ├── api_webrtc.go
│ │ ├── defs.go
│ │ ├── path.go
│ │ ├── path_access_request.go
│ │ ├── publisher.go
│ │ ├── reader.go
│ │ ├── source.go
│ │ └── static_source.go
│ ├── errordumper/
│ │ ├── dumper.go
│ │ └── dumper_test.go
│ ├── externalcmd/
│ │ ├── cmd.go
│ │ ├── cmd_unix.go
│ │ ├── cmd_win.go
│ │ └── pool.go
│ ├── hooks/
│ │ ├── hooks.go
│ │ ├── on_connect.go
│ │ ├── on_demand.go
│ │ ├── on_init.go
│ │ ├── on_read.go
│ │ └── on_ready.go
│ ├── linters/
│ │ ├── conf/
│ │ │ └── conf_test.go
│ │ └── go2api/
│ │ └── go2api_test.go
│ ├── logger/
│ │ ├── destination.go
│ │ ├── destination_file.go
│ │ ├── destination_stdout.go
│ │ ├── destination_syslog.go
│ │ ├── destination_syslog_disabled.go
│ │ ├── level.go
│ │ ├── logger.go
│ │ ├── logger_test.go
│ │ └── writer.go
│ ├── metrics/
│ │ ├── metrics.go
│ │ └── metrics_test.go
│ ├── ntpestimator/
│ │ ├── estimator.go
│ │ └── estimator_test.go
│ ├── packetdumper/
│ │ ├── conn.go
│ │ ├── conn_test.go
│ │ ├── dial_context.go
│ │ ├── listen.go
│ │ ├── listen_packet.go
│ │ ├── listener.go
│ │ ├── packet_conn.go
│ │ └── packet_conn_test.go
│ ├── playback/
│ │ ├── muxer.go
│ │ ├── muxer_fmp4.go
│ │ ├── muxer_mp4.go
│ │ ├── muxer_mp4_test.go
│ │ ├── on_get.go
│ │ ├── on_get_test.go
│ │ ├── on_list.go
│ │ ├── on_list_test.go
│ │ ├── segment_fmp4.go
│ │ ├── segment_fmp4_test.go
│ │ ├── server.go
│ │ └── server_test.go
│ ├── pprof/
│ │ ├── pprof.go
│ │ └── pprof_test.go
│ ├── protocols/
│ │ ├── hls/
│ │ │ ├── from_stream.go
│ │ │ ├── from_stream_test.go
│ │ │ ├── to_stream.go
│ │ │ └── to_stream_test.go
│ │ ├── httpp/
│ │ │ ├── content_type.go
│ │ │ ├── credentials.go
│ │ │ ├── credentials_test.go
│ │ │ ├── handler_exit_on_panic.go
│ │ │ ├── handler_filter_requests.go
│ │ │ ├── handler_filter_requests_test.go
│ │ │ ├── handler_logger.go
│ │ │ ├── handler_origin.go
│ │ │ ├── handler_origin_test.go
│ │ │ ├── handler_server_header.go
│ │ │ ├── handler_tracker.go
│ │ │ ├── handler_tracker_test.go
│ │ │ ├── handler_write_timeout.go
│ │ │ ├── remote_addr.go
│ │ │ ├── server.go
│ │ │ └── server_test.go
│ │ ├── mpegts/
│ │ │ ├── enhanced_reader.go
│ │ │ ├── from_stream.go
│ │ │ ├── from_stream_test.go
│ │ │ ├── to_stream.go
│ │ │ └── to_stream_test.go
│ │ ├── rtmp/
│ │ │ ├── from_stream.go
│ │ │ ├── from_stream_test.go
│ │ │ ├── to_stream.go
│ │ │ └── to_stream_test.go
│ │ ├── rtsp/
│ │ │ ├── credentials.go
│ │ │ ├── credentials_test.go
│ │ │ └── to_stream.go
│ │ ├── tls/
│ │ │ ├── make_config.go
│ │ │ └── make_config_test.go
│ │ ├── udp/
│ │ │ ├── listener.go
│ │ │ ├── listener_test.go
│ │ │ └── params.go
│ │ ├── unix/
│ │ │ ├── listener.go
│ │ │ ├── listener_test.go
│ │ │ └── params.go
│ │ ├── webrtc/
│ │ │ ├── from_stream.go
│ │ │ ├── from_stream_test.go
│ │ │ ├── incoming_track.go
│ │ │ ├── net.go
│ │ │ ├── outgoing_data_channel.go
│ │ │ ├── outgoing_track.go
│ │ │ ├── peer_connection.go
│ │ │ ├── peer_connection_test.go
│ │ │ ├── stats.go
│ │ │ ├── stats_interceptor.go
│ │ │ ├── tcp_mux_wrapper.go
│ │ │ ├── to_stream.go
│ │ │ └── to_stream_test.go
│ │ ├── websocket/
│ │ │ ├── serverconn.go
│ │ │ └── serverconn_test.go
│ │ └── whip/
│ │ ├── client.go
│ │ ├── client_test.go
│ │ ├── ice_fragment.go
│ │ ├── ice_fragment_test.go
│ │ ├── link_header.go
│ │ └── link_header_test.go
│ ├── recordcleaner/
│ │ ├── cleaner.go
│ │ └── cleaner_test.go
│ ├── recorder/
│ │ ├── format.go
│ │ ├── format_fmp4.go
│ │ ├── format_fmp4_part.go
│ │ ├── format_fmp4_segment.go
│ │ ├── format_fmp4_track.go
│ │ ├── format_mpegts.go
│ │ ├── format_mpegts_segment.go
│ │ ├── format_mpegts_track.go
│ │ ├── recorder.go
│ │ ├── recorder_instance.go
│ │ └── recorder_test.go
│ ├── recordstore/
│ │ ├── mp4_boxes.go
│ │ ├── path.go
│ │ ├── path_test.go
│ │ ├── recordstore.go
│ │ ├── segment.go
│ │ └── segment_test.go
│ ├── restrictnetwork/
│ │ └── restrict_network.go
│ ├── rlimit/
│ │ ├── rlimit_unix.go
│ │ └── rlimit_win.go
│ ├── servers/
│ │ ├── hls/
│ │ │ ├── hlsjsdownloader/
│ │ │ │ ├── HASH
│ │ │ │ ├── VERSION
│ │ │ │ └── main.go
│ │ │ ├── http_server.go
│ │ │ ├── index.html
│ │ │ ├── muxer.go
│ │ │ ├── muxer_instance.go
│ │ │ ├── server.go
│ │ │ └── server_test.go
│ │ ├── rtmp/
│ │ │ ├── conn.go
│ │ │ ├── listener.go
│ │ │ ├── server.go
│ │ │ └── server_test.go
│ │ ├── rtsp/
│ │ │ ├── conn.go
│ │ │ ├── mpegts_demuxer.go
│ │ │ ├── server.go
│ │ │ ├── server_test.go
│ │ │ └── session.go
│ │ ├── srt/
│ │ │ ├── conn.go
│ │ │ ├── listener.go
│ │ │ ├── server.go
│ │ │ ├── server_test.go
│ │ │ ├── streamid.go
│ │ │ └── streamid_test.go
│ │ └── webrtc/
│ │ ├── http_server.go
│ │ ├── publish_index.html
│ │ ├── publisher.js
│ │ ├── read_index.html
│ │ ├── reader.js
│ │ ├── server.go
│ │ ├── server_test.go
│ │ └── session.go
│ ├── staticsources/
│ │ ├── handler.go
│ │ ├── hls/
│ │ │ ├── source.go
│ │ │ └── source_test.go
│ │ ├── mpegts/
│ │ │ ├── source.go
│ │ │ └── source_test.go
│ │ ├── rpicamera/
│ │ │ ├── camera_arm32_.go
│ │ │ ├── camera_arm64_.go
│ │ │ ├── camera_arm_.go
│ │ │ ├── camera_other.go
│ │ │ ├── downloader.go
│ │ │ ├── mtxrpicamdownloader/
│ │ │ │ ├── HASH_MTXRPICAM_32_TAR_GZ
│ │ │ │ ├── HASH_MTXRPICAM_64_TAR_GZ
│ │ │ │ ├── VERSION
│ │ │ │ └── main.go
│ │ │ ├── params.go
│ │ │ ├── params_serialize.go
│ │ │ ├── pipe.go
│ │ │ └── source.go
│ │ ├── rtmp/
│ │ │ ├── source.go
│ │ │ └── source_test.go
│ │ ├── rtp/
│ │ │ ├── format.go
│ │ │ ├── media.go
│ │ │ ├── source.go
│ │ │ └── source_test.go
│ │ ├── rtsp/
│ │ │ ├── source.go
│ │ │ └── source_test.go
│ │ ├── srt/
│ │ │ ├── source.go
│ │ │ └── source_test.go
│ │ └── webrtc/
│ │ ├── source.go
│ │ └── source_test.go
│ ├── stream/
│ │ ├── format_updater.go
│ │ ├── offline_sub_stream.go
│ │ ├── offline_sub_stream_track.go
│ │ ├── reader.go
│ │ ├── rtp_decoder.go
│ │ ├── rtp_encoder.go
│ │ ├── stream.go
│ │ ├── stream_alwaysavailable_test.go
│ │ ├── stream_format.go
│ │ ├── stream_media.go
│ │ ├── stream_standard_test.go
│ │ ├── sub_stream.go
│ │ ├── sub_stream_format.go
│ │ ├── sub_stream_media.go
│ │ └── unit_remuxer.go
│ ├── test/
│ │ ├── auth_manager.go
│ │ ├── formats.go
│ │ ├── logger.go
│ │ ├── medias.go
│ │ ├── path_manager.go
│ │ ├── static_source_parent.go
│ │ ├── temp_file.go
│ │ └── tls_cert.go
│ ├── teste2e/
│ │ ├── build_images_test.go
│ │ ├── hls_manager_test.go
│ │ ├── images/
│ │ │ ├── ffmpeg/
│ │ │ │ ├── Dockerfile
│ │ │ │ ├── emptyvideo.mkv
│ │ │ │ ├── emptyvideoaudio.mkv
│ │ │ │ └── start.sh
│ │ │ ├── gstreamer/
│ │ │ │ ├── Dockerfile
│ │ │ │ ├── emptyvideo.mkv
│ │ │ │ ├── exitafterframe.c
│ │ │ │ └── start.sh
│ │ │ └── vlc/
│ │ │ ├── Dockerfile
│ │ │ └── start.sh
│ │ ├── rtsp_server_test.go
│ │ └── tests_test.go
│ └── unit/
│ ├── payload.go
│ ├── payload_ac3.go
│ ├── payload_av1.go
│ ├── payload_g711.go
│ ├── payload_h264.go
│ ├── payload_h265.go
│ ├── payload_klv.go
│ ├── payload_lpcm.go
│ ├── payload_mjpeg.go
│ ├── payload_mpeg1_audio.go
│ ├── payload_mpeg1_video.go
│ ├── payload_mpeg4_audio.go
│ ├── payload_mpeg4_audio_latm.go
│ ├── payload_mpeg4_video.go
│ ├── payload_opus.go
│ ├── payload_vp8.go
│ ├── payload_vp9.go
│ └── unit.go
├── main.go
├── mediamtx.yml
└── scripts/
├── binaries.mk
├── dockerhub.mk
├── format.mk
├── lint.mk
├── test-e2e.mk
├── test.mk
└── winres.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .dockerignore
================================================
# do not add .git, since it is needed to extract the tag
# do not add /binaries, since it is needed by Docker images
/tmp
/coverage*.txt
/api/*.html
/internal/core/VERSION
/internal/servers/hls/hls.min.js
/internal/staticsources/rpicamera/mtxrpicam_*/
================================================
FILE: .github/DISCUSSION_TEMPLATE/questions.yml
================================================
body:
- type: markdown
attributes:
value: |
* Please create a discussion FOR EACH question. Do not ask for multiple questions all at once, otherwise they'll probably never get all answered.
* If you are asking for help because you're having trouble doing something, provide enough informations to replicate the problem. In particular, include in the question:
* MediaMTX version
* precise instructions on how to replicate the problem
* MediaMTX configuration
* MediaMTX logs with setting `logLevel` set to `debug`
* If you are asking for help and you think MediaMTX is misbehaving, open a bug report, NOT a discussion.
- type: textarea
attributes:
label: Question
validations:
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/bug.yml
================================================
name: Bug report
description: Report a bug
body:
- type: markdown
attributes:
value: |
To increase the chance of your bug getting fixed, open an issue FOR EACH bug. Do not report multiple problems in a single issue, otherwise they'll probably never get all fixed.
- type: input
id: version
attributes:
label: Which version are you using?
description: MediaMTX version or commit
validations:
required: true
- type: dropdown
id: os
attributes:
label: Which operating system are you using?
multiple: true
options:
- Linux amd64 standard
- Linux amd64 Docker
- Linux arm64 standard
- Linux arm64 Docker
- Linux arm7 standard
- Linux arm7 Docker
- Linux arm6 standard
- Linux arm6 Docker
- Windows amd64 standard
- Windows amd64 Docker (WSL backend)
- macOS amd64 standard
- macOS amd64 Docker
- Other (please describe)
validations:
required: true
- type: textarea
id: description
attributes:
label: Describe the issue
validations:
required: true
- type: textarea
id: replica
attributes:
label: Describe how to replicate the issue
description: |
The maintainers must be able to REPLICATE your issue to solve it - therefore, describe in a very detailed way how to replicate it.
value: |
1. start the MediaMTX
2. publish with ...
3. read with ...
validations:
required: true
- type: textarea
id: conf
attributes:
label: MediaMTX configuration
description: |
MediaMTX configuration is often required to replicate the issue.
placeholder: Paste the configuration file here
render: yaml
- type: textarea
id: logs
attributes:
label: MediaMTX logs
description: |
MediaMTX logs are often useful to identify the issue. If you think this is the case, set 'logLevel' to 'debug' and attach logs.
placeholder: Paste or drag the log file here
- type: textarea
id: network
attributes:
label: Packet dump
description: |
If the bug arises when using MediaMTX with external hardware or software, the most helpful information you can provide is a packet dump, that can be generated in this way:
1. In mediamtx.yml, set 'dumpPackets' to 'true'
2. Start the server and replicate the issue
3. Stop the server, find the generated .pcapng files in the current directory
4. Attach the pcapng files by dragging them here
placeholder: Attach the pcapng files by dragging them here
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
- name: Question
url: https://github.com/bluenviron/mediamtx/discussions/new?category=questions
about: Ask the community for help
================================================
FILE: .github/ISSUE_TEMPLATE/feature.yml
================================================
name: Feature request
description: Share ideas for new features
body:
- type: markdown
attributes:
value: |
Please create a request FOR EACH feature. Do not report multiple features in a single request, otherwise they'll probably never get all implemented.
- type: textarea
id: description
attributes:
label: Describe the feature
validations:
required: true
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
================================================
FILE: .github/workflows/lint.yml
================================================
name: lint
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
go:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-go@v6
with:
go-version: "1.25"
- run: go generate ./...
- uses: golangci/golangci-lint-action@v9
with:
version: v2.11.3
go_mod:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: "1.25"
- run: make lint-go-mod
conf:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: "1.25"
- run: make lint-conf
go2api:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
- uses: actions/setup-go@v6
with:
go-version: "1.25"
- run: make lint-go2api
docs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
- run: make lint-docs
api_docs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
- run: make lint-api-docs
================================================
FILE: .github/workflows/nightly_binaries.yml
================================================
name: nightly_binaries
on:
workflow_dispatch:
jobs:
nightly_binaries:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- run: make binaries
- uses: actions/upload-artifact@v7
with:
name: binaries
path: binaries
================================================
FILE: .github/workflows/release.yml
================================================
name: release
on:
push:
tags:
- 'v*'
permissions:
id-token: write
attestations: write
artifact-metadata: write
contents: write
issues: write
jobs:
binaries:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
- run: make binaries
- run: cd binaries && sha256sum -b * > checksums.sha256
- uses: actions/attest@v4
with:
subject-path: '${{ github.workspace }}/binaries/*'
- uses: actions/upload-artifact@v7
with:
name: binaries
path: binaries
github_release:
needs: binaries
runs-on: ubuntu-22.04
steps:
- uses: actions/download-artifact@v8
with:
name: binaries
path: binaries
- uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const fs = require('fs').promises;
const { repo: { owner, repo } } = context;
const currentRelease = context.ref.split('/')[2];
let body = `## New major features\n`
+ `\n`
+ `TODO\n`
+ `\n`
+ `## Fixes and improvements\n`
+ `\n`
+ `TODO\n`
+ `\n`
+ `## Security\n`
+ `\n`
+ `Binaries are compiled from source code by the [Release workflow](https://github.com/${owner}/${repo}/actions/workflows/release.yml), which is a fully-visible process that prevents any change or external interference in produced artifacts.\n`
+ `\n`
+ 'Checksums of binaries are also published in a public blockchain by using [GitHub Attestations](https://docs.github.com/en/actions/concepts/security/artifact-attestations), and they can be verified by running:\n'
+ `\n`
+ '```\n'
+ `ls mediamtx_* | xargs -L1 gh attestation verify --repo bluenviron/mediamtx\n`
+ '```\n'
+ `\n`
+ 'You can verify checksums of binaries by downloading `checksums.sha256` and running:\n'
+ `\n`
+ '```\n'
+ `cat checksums.sha256 | grep "$(ls mediamtx_*)" | sha256sum --check\n`
+ '```\n'
+ `\n`;
const res = await github.rest.repos.createRelease({
owner,
repo,
tag_name: currentRelease,
name: currentRelease,
body,
});
const release_id = res.data.id;
for (const name of await fs.readdir('./binaries/')) {
await github.rest.repos.uploadReleaseAsset({
owner,
repo,
release_id,
name,
data: await fs.readFile(`./binaries/${name}`),
});
}
github_notify_issues:
needs: github_release
runs-on: ubuntu-22.04
steps:
- uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { repo: { owner, repo } } = context;
const tags = await github.rest.repos.listTags({
owner,
repo,
});
const curTag = tags.data[0];
const prevTag = tags.data[1];
const diff = await github.rest.repos.compareCommitsWithBasehead({
owner,
repo,
basehead: `${prevTag.commit.sha}...${curTag.commit.sha}`,
});
const issues = {};
for (const commit of diff.data.commits) {
for (const match of commit.commit.message.matchAll(/(^| |\()#([0-9]+)( |\)|$)/g)) {
issues[match[2]] = 1;
}
}
for (const issue in issues) {
try {
await github.rest.issues.createComment({
owner,
repo,
issue_number: parseInt(issue),
body: `This issue is mentioned in release ${curTag.name} 🚀\n`
+ `Check out the entire changelog by [clicking here](https://github.com/${owner}/${repo}/releases/tag/${curTag.name})`,
});
} catch (exc) {
console.error(exc.toString());
}
}
dockerhub:
needs: binaries
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
- uses: actions/download-artifact@v8
with:
name: binaries
path: binaries
- run: make dockerhub
env:
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
================================================
FILE: .github/workflows/test.yml
================================================
name: test
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test_64:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- run: make test
- uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
test_32:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- run: make test-32
test_e2e:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-go@v6
with:
go-version: "1.25"
- run: make test-e2e-nodocker
================================================
FILE: .gitignore
================================================
/tmp
/binaries
/coverage*.txt
/api/*.html
/internal/core/VERSION
/internal/servers/hls/hls.min.js
/internal/staticsources/rpicamera/mtxrpicam_*/
================================================
FILE: .golangci.yml
================================================
version: "2"
linters:
enable:
- asciicheck
- bidichk
- bodyclose
- copyloopvar
- dupl
- errorlint
- gochecknoinits
- gocritic
- lll
- misspell
- modernize
- nilerr
- prealloc
- predeclared
- reassign
- revive
- usestdlibvars
- unconvert
- tparallel
- wastedassign
- whitespace
settings:
errcheck:
exclude-functions:
- io.Copy
- (io.Closer).Close
- (io.Writer).Write
- (hash.Hash).Write
- (net.Conn).Close
- (net.Conn).SetReadDeadline
- (net.Conn).SetWriteDeadline
- (*net.TCPConn).SetKeepAlive
- (*net.TCPConn).SetKeepAlivePeriod
- (*net.TCPConn).SetNoDelay
- (net.Listener).Close
- (net.PacketConn).Close
- (net.PacketConn).SetReadDeadline
- (net.PacketConn).SetWriteDeadline
- (net/http.ResponseWriter).Write
- (*net/http.Server).Serve
- (*net/http.Server).ServeTLS
- (*net/http.Server).Shutdown
- os.Chdir
- os.Mkdir
- os.MkdirAll
- os.Remove
- os.RemoveAll
- os.Setenv
- os.Unsetenv
- (*os.File).WriteString
- (*os.File).Close
- (github.com/datarhei/gosrt.Conn).Close
- (github.com/datarhei/gosrt.Conn).SetReadDeadline
- (github.com/datarhei/gosrt.Conn).SetWriteDeadline
- (*github.com/bluenviron/gortsplib/v5.Client).Close
- (*github.com/bluenviron/gortsplib/v5.Server).Close
- (*github.com/bluenviron/gortsplib/v5.ServerSession).Close
- (*github.com/bluenviron/gortsplib/v5.ServerStream).Close
- (*github.com/bluenviron/gortsplib/v5.ServerConn).Close
govet:
enable-all: true
disable:
- fieldalignment
- reflectvaluecompare
settings:
shadow:
strict: true
modernize:
disable:
- reflecttypefor
- stringsbuilder
- testingcontext
formatters:
enable:
- gofmt
- gofumpt
- goimports
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2019 aler9
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Makefile
================================================
BASE_IMAGE = golang:1.25-alpine3.22
GOLANGCI_LINT_IMAGE = golangci/golangci-lint:v2.11.3
NODE_IMAGE = node:20-alpine3.22
.PHONY: $(shell ls)
help:
@echo "usage: make [action]"
@echo ""
@echo "available actions:"
@echo ""
@echo " format format code"
@echo " test run tests"
@echo " test-32 run tests on a 32-bit system"
@echo " test-e2e run end-to-end tests"
@echo " lint run linters"
@echo " binaries build binaries for all supported platforms"
@echo " dockerhub build and push images to Docker Hub"
@echo ""
blank :=
define NL
$(blank)
endef
include scripts/*.mk
================================================
FILE: README.md
================================================
<h1 align="center">
<a href="https://mediamtx.org">
<img src="logo.png" alt="MediaMTX">
</a>
<br>
<br>
[](https://mediamtx.org)
[](https://github.com/bluenviron/mediamtx/actions/workflows/test.yml?query=branch%3Amain)
[](https://github.com/bluenviron/mediamtx/actions/workflows/lint.yml?query=branch%3Amain)
[](https://app.codecov.io/gh/bluenviron/mediamtx/tree/main)
[](https://github.com/bluenviron/mediamtx/releases)
[](https://hub.docker.com/r/bluenviron/mediamtx)
</h1>
<br>
_MediaMTX_ is a ready-to-use and zero-dependency real-time media server and media proxy that allows to publish, read, proxy, record and playback video and audio streams. It has been conceived as a "media router" that routes media streams from one end to the other, with a focus on efficiency and portability.
<div align="center">
|[Install](https://mediamtx.org/docs/kickoff/install)|[Documentation](https://mediamtx.org/docs/kickoff/introduction)|
|-|-|
</div>
<h3>Features</h3>
- [Publish](https://mediamtx.org/docs/usage/publish) live streams to the server with SRT, WebRTC, RTSP, RTMP, HLS, MPEG-TS, RTP, using FFmpeg, GStreamer, OBS Studio, Python , Golang, Unity, web browsers, Raspberry Pi Cameras and more.
- [Read](https://mediamtx.org/docs/usage/read) live streams from the server with SRT, WebRTC, RTSP, RTMP, HLS, using FFmpeg, GStreamer, VLC, OBS Studio, Python , Golang, Unity, web browsers and more.
- Streams are automatically converted from a protocol to another
- Serve several streams at once in separate paths
- Reload the configuration without disconnecting existing clients (hot reloading)
- [Serve always-available streams](https://mediamtx.org/docs/usage/always-available) even when the publisher is offline
- [Record](https://mediamtx.org/docs/usage/record) streams to disk in fMP4 or MPEG-TS format
- [Playback](https://mediamtx.org/docs/usage/playback) recorded streams
- [Authenticate](https://mediamtx.org/docs/usage/authentication) users with internal, HTTP or JWT authentication
- [Forward](https://mediamtx.org/docs/usage/forward) streams to other servers
- [Proxy](https://mediamtx.org/docs/usage/proxy) requests to other servers
- [Control](https://mediamtx.org/docs/usage/control-api) the server through the Control API
- [Extract metrics](https://mediamtx.org/docs/usage/metrics) from the server in a Prometheus-compatible format
- [Monitor performance](https://mediamtx.org/docs/usage/performance) to investigate CPU and RAM consumption
- [Run hooks](https://mediamtx.org/docs/usage/hooks) (external commands) when clients connect, disconnect, read or publish streams
- Compatible with Linux, Windows and macOS, does not require any dependency or interpreter, it's a single executable
- ...and many [others](https://mediamtx.org/docs/kickoff/introduction).
================================================
FILE: SECURITY.md
================================================
# Security
Check the [Security page](https://mediamtx.org/docs/other/security) on the website.
================================================
FILE: api/.redocly.yaml
================================================
extends:
- recommended
rules:
operation-4xx-response: off
================================================
FILE: api/openapi.yaml
================================================
openapi: 3.0.0
info:
version: 1.0.0
title: MediaMTX API
description: API of MediaMTX, a server and proxy that supports various protocols.
license:
name: MIT
url: https://opensource.org/licenses/MIT
servers:
- url: http://localhost:9997
security: []
components:
schemas:
OKStatus:
type: string
enum: [ok]
ErrorStatus:
type: string
enum: [error]
PathSourceType:
type: string
enum:
- hlsSource
- redirect
- rpiCameraSource
- rtmpConn
- rtmpsConn
- rtmpSource
- rtspSession
- rtspSource
- rtspsSession
- srtConn
- srtSource
- mpegtsSource
- rtpSource
- webRTCSession
- webRTCSource
PathReaderType:
type: string
enum:
- hlsMuxer
- rpiCameraSecondary
- rtmpConn
- rtmpsConn
- rtspConn
- rtspSession
- rtspsConn
- rtspsSession
- srtConn
- webRTCSession
PathTrackCodec:
type: string
enum:
- AV1
- VP9
- VP8
- H265
- H264
- MPEG-4 Video
- MPEG-1 Video
- MJPEG
- Opus
- Vorbis
- MPEG-4 Audio
- MPEG-4 Audio LATM
- MPEG-1 Audio
- AC3
- Speex
- G726
- G722
- G711
- LPCM
- MPEG-TS
- KLV
- Generic
AlwaysAvailableTrackCodec:
type: string
enum:
- AV1
- VP9
- H265
- H264
- MPEG4Audio
- Opus
- G711
- LPCM
AuthAction:
type: string
enum:
- publish
- read
- playback
- api
- metrics
- pprof
AuthMethod:
type: string
enum: [internal, http, jwt]
Encryption:
type: string
enum: [no, optional, strict]
HLSVariant:
type: string
enum: [mpegts, fmp4, lowLatency]
LogDestination:
type: string
enum: [stdout, file, syslog]
LogLevel:
type: string
enum: [error, warn, info, debug]
RecordFormat:
type: string
enum: [fmp4, mpegts]
RTSPAuthMethod:
type: string
enum: [basic, digest]
RTSPRangeType:
type: string
enum: ['', clock, npt, smpte]
RTSPTransport:
type: string
enum: [udp, multicast, tcp, automatic]
RTMPConnState:
type: string
enum: [idle, read, publish]
RTSPSessionState:
type: string
enum: [idle, read, publish]
SRTConnState:
type: string
enum: [idle, read, publish]
WebRTCSessionState:
type: string
enum: [read, publish]
OK:
type: object
properties:
status:
$ref: '#/components/schemas/OKStatus'
Error:
type: object
properties:
status:
$ref: '#/components/schemas/ErrorStatus'
error:
type: string
Info:
type: object
properties:
version:
type: string
started:
type: string
AuthInternalUser:
type: object
properties:
user:
type: string
pass:
type: string
ips:
type: array
items:
type: string
permissions:
type: array
items:
$ref: '#/components/schemas/AuthInternalUserPermission'
AuthInternalUserPermission:
type: object
properties:
action:
$ref: '#/components/schemas/AuthAction'
path:
type: string
GlobalConf:
type: object
properties:
# General
logLevel:
$ref: '#/components/schemas/LogLevel'
logDestinations:
type: array
items:
$ref: '#/components/schemas/LogDestination'
logStructured:
type: boolean
logFile:
type: string
sysLogPrefix:
type: string
dumpPackets:
type: boolean
readTimeout:
type: string
writeTimeout:
type: string
readBufferCount:
type: integer
format: int64
nullable: true
deprecated: true
writeQueueSize:
type: integer
format: int64
udpMaxPayloadSize:
type: integer
format: int64
udpReadBufferSize:
type: integer
format: uint64
runOnConnect:
type: string
runOnConnectRestart:
type: boolean
runOnDisconnect:
type: string
# Authentication
authMethod:
$ref: '#/components/schemas/AuthMethod'
authInternalUsers:
type: array
items:
$ref: '#/components/schemas/AuthInternalUser'
authHTTPAddress:
type: string
externalAuthenticationURL:
type: string
nullable: true
deprecated: true
authHTTPFingerprint:
type: string
authHTTPExclude:
type: array
items:
$ref: '#/components/schemas/AuthInternalUserPermission'
authJWTJWKS:
type: string
authJWTJWKSFingerprint:
type: string
authJWTClaimKey:
type: string
authJWTIssuer:
type: string
authJWTAudience:
type: string
authJWTExclude:
type: array
items:
$ref: '#/components/schemas/AuthInternalUserPermission'
authJWTInHTTPQuery:
type: boolean
# Control API
api:
type: boolean
apiAddress:
type: string
apiEncryption:
type: boolean
apiServerKey:
type: string
apiServerCert:
type: string
apiAllowOrigin:
type: string
nullable: true
deprecated: true
apiAllowOrigins:
type: array
items:
type: string
apiTrustedProxies:
type: array
items:
type: string
# Metrics
metrics:
type: boolean
metricsAddress:
type: string
metricsEncryption:
type: boolean
metricsServerKey:
type: string
metricsServerCert:
type: string
metricsAllowOrigin:
type: string
nullable: true
deprecated: true
metricsAllowOrigins:
type: array
items:
type: string
metricsTrustedProxies:
type: array
items:
type: string
# PPROF
pprof:
type: boolean
pprofAddress:
type: string
pprofEncryption:
type: boolean
pprofServerKey:
type: string
pprofServerCert:
type: string
pprofAllowOrigin:
type: string
nullable: true
deprecated: true
pprofAllowOrigins:
type: array
items:
type: string
pprofTrustedProxies:
type: array
items:
type: string
# Playback server
playback:
type: boolean
playbackAddress:
type: string
playbackEncryption:
type: boolean
playbackServerKey:
type: string
playbackServerCert:
type: string
playbackAllowOrigin:
type: string
nullable: true
deprecated: true
playbackAllowOrigins:
type: array
items:
type: string
playbackTrustedProxies:
type: array
items:
type: string
# RTSP server
rtsp:
type: boolean
rtspDisable:
type: boolean
nullable: true
deprecated: true
protocols:
type: array
nullable: true
items:
type: string
enum: [udp, multicast, tcp]
deprecated: true
rtspTransports:
type: array
items:
type: string
enum: [udp, multicast, tcp]
encryption:
type: string
nullable: true
deprecated: true
allOf:
- $ref: '#/components/schemas/Encryption'
rtspEncryption:
$ref: '#/components/schemas/Encryption'
rtspAddress:
type: string
rtspsAddress:
type: string
rtpAddress:
type: string
rtcpAddress:
type: string
multicastIPRange:
type: string
multicastRTPPort:
type: integer
format: int64
multicastRTCPPort:
type: integer
format: int64
srtpAddress:
type: string
srtcpAddress:
type: string
multicastSRTPPort:
type: integer
format: int64
multicastSRTCPPort:
type: integer
format: int64
rtspServerKey:
type: string
rtspServerCert:
type: string
authMethods:
type: array
nullable: true
items:
$ref: '#/components/schemas/RTSPAuthMethod'
deprecated: true
rtspAuthMethods:
type: array
items:
$ref: '#/components/schemas/RTSPAuthMethod'
rtspUDPReadBufferSize:
type: integer
format: uint64
nullable: true
deprecated: true
# RTMP server
rtmp:
type: boolean
rtmpDisable:
type: boolean
nullable: true
deprecated: true
rtmpEncryption:
$ref: '#/components/schemas/Encryption'
rtmpAddress:
type: string
rtmpsAddress:
type: string
rtmpServerKey:
type: string
rtmpServerCert:
type: string
# HLS server
hls:
type: boolean
hlsDisable:
type: boolean
nullable: true
deprecated: true
hlsAddress:
type: string
hlsEncryption:
type: boolean
hlsServerKey:
type: string
hlsServerCert:
type: string
hlsAllowOrigin:
type: string
nullable: true
deprecated: true
hlsAllowOrigins:
type: array
items:
type: string
hlsTrustedProxies:
type: array
items:
type: string
hlsAlwaysRemux:
type: boolean
hlsVariant:
$ref: '#/components/schemas/HLSVariant'
hlsSegmentCount:
type: integer
format: int64
hlsSegmentDuration:
type: string
hlsPartDuration:
type: string
hlsSegmentMaxSize:
type: string
hlsDirectory:
type: string
hlsMuxerCloseAfter:
type: string
# WebRTC server
webrtc:
type: boolean
webrtcDisable:
type: boolean
nullable: true
deprecated: true
webrtcAddress:
type: string
webrtcEncryption:
type: boolean
webrtcServerKey:
type: string
webrtcServerCert:
type: string
webrtcAllowOrigin:
type: string
nullable: true
deprecated: true
webrtcAllowOrigins:
type: array
items:
type: string
webrtcTrustedProxies:
type: array
items:
type: string
webrtcLocalUDPAddress:
type: string
webrtcLocalTCPAddress:
type: string
webrtcIPsFromInterfaces:
type: boolean
webrtcIPsFromInterfacesList:
type: array
items:
type: string
webrtcAdditionalHosts:
type: array
items:
type: string
webrtcICEServers2:
type: array
items:
$ref: '#/components/schemas/WebRTCICEServer'
webrtcSTUNGatherTimeout:
type: string
webrtcHandshakeTimeout:
type: string
webrtcTrackGatherTimeout:
type: string
webrtcICEUDPMuxAddress:
type: string
nullable: true
deprecated: true
webrtcICETCPMuxAddress:
type: string
nullable: true
deprecated: true
webrtcICEHostNAT1To1IPs:
type: array
nullable: true
items:
type: string
deprecated: true
webrtcICEServers:
type: array
nullable: true
items:
type: string
deprecated: true
# SRT server
srt:
type: boolean
srtAddress:
type: string
# Record (deprecated)
record:
type: boolean
nullable: true
deprecated: true
recordPath:
type: string
nullable: true
deprecated: true
recordFormat:
type: string
nullable: true
deprecated: true
allOf:
- $ref: '#/components/schemas/RecordFormat'
recordPartDuration:
type: string
nullable: true
deprecated: true
recordSegmentDuration:
type: string
nullable: true
deprecated: true
recordDeleteAfter:
type: string
nullable: true
deprecated: true
PathConf:
type: object
properties:
name:
type: string
# General
source:
type: string
sourceFingerprint:
type: string
sourceOnDemand:
type: boolean
sourceOnDemandStartTimeout:
type: string
sourceOnDemandCloseAfter:
type: string
maxReaders:
type: integer
format: int64
srtReadPassphrase:
type: string
fallback:
type: string
nullable: true
deprecated: true
useAbsoluteTimestamp:
type: boolean
# Always available
alwaysAvailable:
type: boolean
alwaysAvailableTracks:
type: array
items:
$ref: '#/components/schemas/AlwaysAvailableTrack'
alwaysAvailableFile:
type: string
# Record
record:
type: boolean
playback:
type: boolean
nullable: true
deprecated: true
recordPath:
type: string
recordFormat:
$ref: '#/components/schemas/RecordFormat'
recordPartDuration:
type: string
recordMaxPartSize:
type: string
recordSegmentDuration:
type: string
recordDeleteAfter:
type: string
# Authentication (deprecated)
publishUser:
type: string
nullable: true
deprecated: true
publishPass:
type: string
nullable: true
deprecated: true
publishIPs:
type: array
nullable: true
items:
type: string
deprecated: true
readUser:
type: string
nullable: true
deprecated: true
readPass:
type: string
nullable: true
deprecated: true
readIPs:
type: array
nullable: true
items:
type: string
deprecated: true
# Publisher source
overridePublisher:
type: boolean
disablePublisherOverride:
type: boolean
nullable: true
deprecated: true
srtPublishPassphrase:
type: string
rtspDemuxMpegts:
type: boolean
# RTSP source
rtspTransport:
$ref: '#/components/schemas/RTSPTransport'
rtspAnyPort:
type: boolean
sourceProtocol:
type: string
nullable: true
deprecated: true
allOf:
- $ref: '#/components/schemas/RTSPTransport'
sourceAnyPortEnable:
type: boolean
nullable: true
deprecated: true
rtspRangeType:
$ref: '#/components/schemas/RTSPRangeType'
rtspRangeStart:
type: string
rtspUDPReadBufferSize:
type: integer
format: uint64
nullable: true
deprecated: true
rtspUDPSourcePortRange:
type: array
minItems: 2
maxItems: 2
items:
type: integer
format: uint64
# MPEG-TS source
mpegtsUDPReadBufferSize:
type: integer
format: uint64
nullable: true
deprecated: true
# RTP source
rtpSDP:
type: string
rtpUDPReadBufferSize:
type: integer
format: uint64
nullable: true
deprecated: true
# WHEP source
whepBearerToken:
type: string
whepSTUNGatherTimeout:
type: string
whepHandshakeTimeout:
type: string
whepTrackGatherTimeout:
type: string
# Redirect source
sourceRedirect:
type: string
# Raspberry Pi Camera source
rpiCameraCamID:
type: integer
format: uint64
rpiCameraSecondary:
type: boolean
rpiCameraWidth:
type: integer
format: uint64
rpiCameraHeight:
type: integer
format: uint64
rpiCameraHFlip:
type: boolean
rpiCameraVFlip:
type: boolean
rpiCameraBrightness:
type: number
format: double
rpiCameraContrast:
type: number
format: double
rpiCameraSaturation:
type: number
format: double
rpiCameraSharpness:
type: number
format: double
rpiCameraExposure:
type: string
rpiCameraAWB:
type: string
rpiCameraAWBGains:
type: array
minItems: 2
maxItems: 2
items:
type: number
format: double
rpiCameraDenoise:
type: string
rpiCameraShutter:
type: integer
format: uint64
rpiCameraMetering:
type: string
rpiCameraGain:
type: number
format: double
rpiCameraEV:
type: number
format: double
rpiCameraROI:
type: string
rpiCameraHDR:
type: boolean
rpiCameraTuningFile:
type: string
rpiCameraMode:
type: string
rpiCameraFPS:
type: number
format: double
rpiCameraAfMode:
type: string
rpiCameraAfRange:
type: string
rpiCameraAfSpeed:
type: string
rpiCameraLensPosition:
type: number
format: double
rpiCameraAfWindow:
type: string
rpiCameraFlickerPeriod:
type: integer
format: uint64
rpiCameraTextOverlayEnable:
type: boolean
rpiCameraTextOverlay:
type: string
rpiCameraCodec:
type: string
rpiCameraIDRPeriod:
type: integer
format: uint64
rpiCameraBitrate:
type: integer
format: uint64
rpiCameraProfile:
type: string
nullable: true
deprecated: true
rpiCameraLevel:
type: string
nullable: true
deprecated: true
rpiCameraHardwareH264Profile:
type: string
rpiCameraHardwareH264Level:
type: string
rpiCameraSoftwareH264Profile:
type: string
rpiCameraSoftwareH264Level:
type: string
rpiCameraJPEGQuality:
type: integer
format: uint64
nullable: true
deprecated: true
rpiCameraMJPEGQuality:
type: integer
format: uint64
# Hooks
runOnInit:
type: string
runOnInitRestart:
type: boolean
runOnDemand:
type: string
runOnDemandRestart:
type: boolean
runOnDemandStartTimeout:
type: string
runOnDemandCloseAfter:
type: string
runOnUnDemand:
type: string
runOnReady:
type: string
runOnReadyRestart:
type: boolean
runOnNotReady:
type: string
runOnRead:
type: string
runOnReadRestart:
type: boolean
runOnUnread:
type: string
runOnRecordSegmentCreate:
type: string
runOnRecordSegmentComplete:
type: string
PathConfList:
type: object
properties:
pageCount:
type: integer
format: int64
itemCount:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/PathConf'
Path:
type: object
properties:
name:
type: string
confName:
type: string
source:
type: object
nullable: true
allOf:
- $ref: '#/components/schemas/PathSource'
ready:
type: boolean
deprecated: true
readyTime:
type: string
nullable: true
deprecated: true
available:
type: boolean
availableTime:
type: string
nullable: true
online:
type: boolean
onlineTime:
type: string
nullable: true
tracks:
type: array
deprecated: true
items:
$ref: '#/components/schemas/PathTrackCodec'
tracks2:
type: array
items:
$ref: '#/components/schemas/PathTrack'
inboundBytes:
type: integer
format: uint64
outboundBytes:
type: integer
format: uint64
inboundFramesInError:
type: integer
format: uint64
bytesReceived:
type: integer
format: uint64
deprecated: true
bytesSent:
type: integer
format: uint64
deprecated: true
readers:
type: array
items:
$ref: '#/components/schemas/PathReader'
PathList:
type: object
properties:
pageCount:
type: integer
format: int64
itemCount:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/Path'
PathSource:
type: object
properties:
type:
$ref: '#/components/schemas/PathSourceType'
id:
type: string
PathReader:
type: object
properties:
type:
$ref: '#/components/schemas/PathReaderType'
id:
type: string
PathTrack:
type: object
properties:
codec:
$ref: '#/components/schemas/PathTrackCodec'
codecProps:
type: object
nullable: true
allOf:
- $ref: '#/components/schemas/PathTrackCodecProps'
PathTrackCodecProps:
oneOf:
- $ref: '#/components/schemas/PathTrackCodecPropsAV1'
- $ref: '#/components/schemas/PathTrackCodecPropsVP9'
- $ref: '#/components/schemas/PathTrackCodecPropsH265'
- $ref: '#/components/schemas/PathTrackCodecPropsH264'
- $ref: '#/components/schemas/PathTrackCodecPropsOpus'
- $ref: '#/components/schemas/PathTrackCodecPropsMPEG4Audio'
- $ref: '#/components/schemas/PathTrackCodecPropsAC3'
- $ref: '#/components/schemas/PathTrackCodecPropsG711'
- $ref: '#/components/schemas/PathTrackCodecPropsLPCM'
PathTrackCodecPropsAV1:
type: object
properties:
width:
type: integer
format: int64
height:
type: integer
format: int64
profile:
type: integer
format: int64
level:
type: integer
format: int64
tier:
type: integer
format: int64
PathTrackCodecPropsVP9:
type: object
properties:
profile:
type: integer
format: int64
PathTrackCodecPropsH265:
type: object
properties:
width:
type: integer
format: int64
height:
type: integer
format: int64
profile:
type: string
level:
type: string
PathTrackCodecPropsH264:
type: object
properties:
width:
type: integer
format: int64
height:
type: integer
format: int64
profile:
type: string
level:
type: string
PathTrackCodecPropsOpus:
type: object
properties:
channelCount:
type: integer
format: int64
PathTrackCodecPropsMPEG4Audio:
type: object
properties:
sampleRate:
type: integer
format: int64
channelCount:
type: integer
format: int64
PathTrackCodecPropsAC3:
type: object
properties:
sampleRate:
type: integer
format: int64
channelCount:
type: integer
format: int64
PathTrackCodecPropsG711:
type: object
properties:
muLaw:
type: boolean
sampleRate:
type: integer
format: int64
channelCount:
type: integer
format: int64
PathTrackCodecPropsLPCM:
type: object
properties:
bitDepth:
type: integer
format: int64
sampleRate:
type: integer
format: int64
channelCount:
type: integer
format: int64
HLSMuxer:
type: object
properties:
path:
type: string
created:
type: string
lastRequest:
type: string
outboundBytes:
type: integer
format: uint64
outboundFramesDiscarded:
type: integer
format: uint64
bytesSent:
type: integer
format: uint64
deprecated: true
HLSMuxerList:
type: object
properties:
pageCount:
type: integer
format: int64
itemCount:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/HLSMuxer'
Recording:
type: object
properties:
name:
type: string
segments:
type: array
items:
$ref: '#/components/schemas/RecordingSegment'
RecordingList:
type: object
properties:
pageCount:
type: integer
format: int64
itemCount:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/Recording'
RecordingSegment:
type: object
properties:
start:
type: string
RTMPConn:
type: object
properties:
id:
type: string
format: uuid
created:
type: string
remoteAddr:
type: string
state:
$ref: '#/components/schemas/RTMPConnState'
path:
type: string
query:
type: string
user:
type: string
inboundBytes:
type: integer
format: uint64
outboundBytes:
type: integer
format: uint64
outboundFramesDiscarded:
type: integer
format: uint64
bytesReceived:
type: integer
format: uint64
deprecated: true
bytesSent:
type: integer
format: uint64
deprecated: true
RTMPConnList:
type: object
properties:
pageCount:
type: integer
format: int64
itemCount:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/RTMPConn'
RTSPConn:
type: object
properties:
id:
type: string
format: uuid
created:
type: string
remoteAddr:
type: string
session:
type: string
format: uuid
nullable: true
tunnel:
type: string
inboundBytes:
type: integer
format: uint64
outboundBytes:
type: integer
format: uint64
bytesReceived:
type: integer
format: uint64
deprecated: true
bytesSent:
type: integer
format: uint64
deprecated: true
RTSPConnList:
type: object
properties:
pageCount:
type: integer
format: int64
itemCount:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/RTSPConn'
RTSPSession:
type: object
properties:
id:
type: string
format: uuid
created:
type: string
remoteAddr:
type: string
state:
$ref: '#/components/schemas/RTSPSessionState'
path:
type: string
query:
type: string
user:
type: string
transport:
type: string
nullable: true
profile:
type: string
nullable: true
conns:
type: array
items:
type: string
format: uuid
inboundBytes:
type: integer
format: uint64
inboundRTPPackets:
type: integer
format: uint64
inboundRTPPacketsLost:
type: integer
format: uint64
inboundRTPPacketsInError:
type: integer
format: uint64
inboundRTPPacketsJitter:
type: number
format: double
inboundRTCPPackets:
type: integer
format: uint64
inboundRTCPPacketsInError:
type: integer
format: uint64
outboundBytes:
type: integer
format: uint64
outboundRTPPackets:
type: integer
format: uint64
outboundRTPPacketsReportedLost:
type: integer
format: uint64
outboundRTPPacketsDiscarded:
type: integer
format: uint64
outboundRTCPPackets:
type: integer
format: uint64
bytesReceived:
type: integer
format: uint64
deprecated: true
bytesSent:
type: integer
format: uint64
deprecated: true
rtpPacketsReceived:
type: integer
format: uint64
deprecated: true
rtpPacketsSent:
type: integer
format: uint64
deprecated: true
rtpPacketsLost:
type: integer
format: uint64
deprecated: true
rtpPacketsInError:
type: integer
format: uint64
deprecated: true
rtpPacketsJitter:
type: number
format: double
deprecated: true
rtcpPacketsReceived:
type: integer
format: uint64
deprecated: true
rtcpPacketsSent:
type: integer
format: uint64
deprecated: true
rtcpPacketsInError:
type: integer
format: uint64
deprecated: true
RTSPSessionList:
type: object
properties:
pageCount:
type: integer
format: int64
itemCount:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/RTSPSession'
SRTConn:
type: object
properties:
id:
type: string
format: uuid
created:
type: string
remoteAddr:
type: string
state:
$ref: '#/components/schemas/SRTConnState'
path:
type: string
query:
type: string
user:
type: string
packetsSent:
type: integer
format: uint64
description: The total number of sent DATA packets, including retransmitted packets
packetsReceived:
type: integer
format: uint64
description: The total number of received DATA packets, including retransmitted packets
packetsReceivedBelated:
type: integer
format: uint64
packetsSentUnique:
type: integer
format: uint64
description: The total number of unique DATA packets sent by the SRT sender
packetsReceivedUnique:
type: integer
format: uint64
description: The total number of unique original, retransmitted or recovered by the packet filter DATA packets received in time, decrypted without errors and, as a result, scheduled for delivery to the upstream application by the SRT receiver.
packetsSendLoss:
type: integer
format: uint64
description: The total number of data packets considered or reported as lost at the sender side. Does not correspond to the packets detected as lost at the receiver side.
packetsReceivedLoss:
type: integer
format: uint64
description: The total number of SRT DATA packets detected as presently missing (either reordered or lost) at the receiver side
packetsRetrans:
type: integer
format: uint64
description: The total number of retransmitted packets sent by the SRT sender
packetsReceivedRetrans:
type: integer
format: uint64
description: The total number of retransmitted packets registered at the receiver side
packetsSentACK:
type: integer
format: uint64
description: The total number of sent ACK (Acknowledgement) control packets
packetsReceivedACK:
type: integer
format: uint64
description: The total number of received ACK (Acknowledgement) control packets
packetsSentNAK:
type: integer
format: uint64
description: The total number of sent NAK (Negative Acknowledgement) control packets
packetsReceivedNAK:
type: integer
format: uint64
description: The total number of received NAK (Negative Acknowledgement) control packets
packetsSentKM:
type: integer
format: uint64
description: The total number of sent KM (Key Material) control packets
packetsReceivedKM:
type: integer
format: uint64
description: The total number of received KM (Key Material) control packets
usSndDuration:
type: integer
format: uint64
description: The total accumulated time in microseconds, during which the SRT sender has some data to transmit, including packets that have been sent, but not yet acknowledged
packetsSendDrop:
type: integer
format: uint64
description: The total number of dropped by the SRT sender DATA packets that have no chance to be delivered in time
packetsReceivedDrop:
type: integer
format: uint64
description: The total number of dropped by the SRT receiver and, as a result, not delivered to the upstream application DATA packets
packetsReceivedUndecrypt:
type: integer
format: uint64
description: The total number of packets that failed to be decrypted at the receiver side
bytesSent:
type: integer
format: uint64
description: Same as packetsSent, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
bytesReceived:
type: integer
format: uint64
description: Same as packetsReceived, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
bytesReceivedBelated:
type: integer
format: uint64
bytesSentUnique:
type: integer
format: uint64
description: Same as packetsSentUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
bytesReceivedUnique:
type: integer
format: uint64
description: Same as packetsReceivedUnique, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
bytesReceivedLoss:
type: integer
format: uint64
description: Same as packetsReceivedLoss, but expressed in bytes, including payload and all the headers (IP, TCP, SRT), bytes for the presently missing (either reordered or lost) packets' payloads are estimated based on the average packet size
bytesRetrans:
type: integer
format: uint64
description: Same as packetsRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
bytesReceivedRetrans:
type: integer
format: uint64
description: Same as packetsReceivedRetrans, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
bytesSendDrop:
type: integer
format: uint64
description: Same as packetsSendDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
bytesReceivedDrop:
type: integer
format: uint64
description: Same as packetsReceivedDrop, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
bytesReceivedUndecrypt:
type: integer
format: uint64
description: Same as packetsReceivedUndecrypt, but expressed in bytes, including payload and all the headers (IP, TCP, SRT)
usPacketsSendPeriod:
type: number
format: double
description: Current minimum time interval between which consecutive packets are sent, in microseconds
packetsFlowWindow:
type: integer
format: uint64
description: The maximum number of packets that can be "in flight"
packetsFlightSize:
type: integer
format: uint64
description: The number of packets in flight
msRTT:
type: number
format: double
description: Smoothed round-trip time (SRTT), an exponentially-weighted moving average (EWMA) of an endpoint's RTT samples, in milliseconds
mbpsSendRate:
type: number
format: double
description: Current transmission bandwidth, in Mbps
mbpsReceiveRate:
type: number
format: double
description: Current receiving bandwidth, in Mbps
mbpsLinkCapacity:
type: number
format: double
description: Estimated capacity of the network link, in Mbps
bytesAvailSendBuf:
type: integer
format: uint64
description: The available space in the sender's buffer, in bytes
bytesAvailReceiveBuf:
type: integer
format: uint64
description: The available space in the receiver's buffer, in bytes
mbpsMaxBW:
type: number
format: double
description: Transmission bandwidth limit, in Mbps
byteMSS:
type: integer
format: uint64
description: Maximum Segment Size (MSS), in bytes
packetsSendBuf:
type: integer
format: uint64
description: The number of packets in the sender's buffer that are already scheduled for sending or even possibly sent, but not yet acknowledged
bytesSendBuf:
type: integer
format: uint64
description: Instantaneous (current) value of packetsSndBuf, but expressed in bytes, including payload and all headers (IP, TCP, SRT)
msSendBuf:
type: integer
format: uint64
description: The timespan (msec) of packets in the sender's buffer (unacknowledged packets)
msSendTsbPdDelay:
type: integer
format: uint64
description: Timestamp-based Packet Delivery Delay value of the peer
packetsReceiveBuf:
type: integer
format: uint64
description: The number of acknowledged packets in receiver's buffer
bytesReceiveBuf:
type: integer
format: uint64
description: Instantaneous (current) value of packetsRcvBuf, expressed in bytes, including payload and all headers (IP, TCP, SRT)
msReceiveBuf:
type: integer
format: uint64
description: The timespan (msec) of acknowledged packets in the receiver's buffer
msReceiveTsbPdDelay:
type: integer
format: uint64
description: Timestamp-based Packet Delivery Delay value set on the socket via SRTO_RCVLATENCY or SRTO_LATENCY
packetsReorderTolerance:
type: integer
format: uint64
description: Instant value of the packet reorder tolerance
packetsReceivedAvgBelatedTime:
type: integer
format: uint64
description: Accumulated difference between the current time and the time-to-play of a packet that is received late
packetsSendLossRate:
type: number
format: double
description: Percentage of resent data vs. sent data
packetsReceivedLossRate:
type: number
format: double
description: Percentage of retransmitted data vs. received data
outboundFramesDiscarded:
type: integer
format: uint64
SRTConnList:
type: object
properties:
pageCount:
type: integer
format: int64
itemCount:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/SRTConn'
AlwaysAvailableTrack:
type: object
properties:
codec:
$ref: '#/components/schemas/AlwaysAvailableTrackCodec'
sampleRate:
type: integer
format: int64
channelCount:
type: integer
format: int64
muLaw:
type: boolean
WebRTCICEServer:
type: object
properties:
url:
type: string
username:
type: string
password:
type: string
clientOnly:
type: boolean
WebRTCSession:
type: object
properties:
id:
type: string
format: uuid
created:
type: string
remoteAddr:
type: string
peerConnectionEstablished:
type: boolean
localCandidate:
type: string
remoteCandidate:
type: string
state:
$ref: '#/components/schemas/WebRTCSessionState'
path:
type: string
query:
type: string
user:
type: string
inboundBytes:
type: integer
format: uint64
inboundRTPPackets:
type: integer
format: uint64
inboundRTPPacketsLost:
type: integer
format: uint64
inboundRTPPacketsJitter:
type: number
format: double
inboundRTCPPackets:
type: integer
format: uint64
outboundBytes:
type: integer
format: uint64
outboundRTPPackets:
type: integer
format: uint64
outboundRTCPPackets:
type: integer
format: uint64
outboundFramesDiscarded:
type: integer
format: uint64
bytesReceived:
type: integer
format: uint64
deprecated: true
bytesSent:
type: integer
format: uint64
deprecated: true
rtpPacketsReceived:
type: integer
format: uint64
deprecated: true
rtpPacketsSent:
type: integer
format: uint64
deprecated: true
rtpPacketsLost:
type: integer
format: uint64
deprecated: true
rtpPacketsJitter:
type: number
format: double
deprecated: true
rtcpPacketsReceived:
type: integer
format: uint64
deprecated: true
rtcpPacketsSent:
type: integer
format: uint64
deprecated: true
WebRTCSessionList:
type: object
properties:
pageCount:
type: integer
format: int64
itemCount:
type: integer
format: int64
items:
type: array
items:
$ref: '#/components/schemas/WebRTCSession'
paths:
/v3/info:
get:
operationId: info
tags: [General]
summary: returns informations about the instance.
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/Info'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/auth/jwks/refresh:
post:
operationId: authJwksRefresh
tags: [Authentication]
summary: Manually refreshes the JWT JWKS.
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/global/get:
get:
operationId: configGlobalGet
tags: [Configuration]
summary: returns the global configuration.
description: ''
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/GlobalConf'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/global/patch:
patch:
operationId: configGlobalSet
tags: [Configuration]
summary: patches the global configuration.
description: all fields are optional.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/GlobalConf'
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/pathdefaults/get:
get:
operationId: configPathDefaultsGet
tags: [Configuration]
summary: returns the default path configuration.
description: ''
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/PathConf'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/pathdefaults/patch:
patch:
operationId: configPathDefaultsPatch
tags: [Configuration]
summary: patches the default path configuration.
description: all fields are optional.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PathConf'
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/paths/list:
get:
operationId: configPathsList
tags: [Configuration]
summary: returns all path configurations.
description: ''
parameters:
- name: page
in: query
description: page number.
schema:
type: integer
default: 0
- name: itemsPerPage
in: query
description: items per page.
schema:
type: integer
default: 100
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/PathConfList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/paths/get/{name}:
get:
operationId: configPathsGet
tags: [Configuration]
summary: returns a path configuration.
description: ''
parameters:
- name: name
in: path
required: true
description: the name of the path.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/PathConf'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: path not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/paths/add/{name}:
post:
operationId: configPathsAdd
tags: [Configuration]
summary: adds a path configuration.
description: all fields are optional.
parameters:
- name: name
in: path
required: true
description: the name of the path.
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PathConf'
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/paths/patch/{name}:
patch:
operationId: configPathsPatch
tags: [Configuration]
summary: patches a path configuration.
description: all fields are optional.
parameters:
- name: name
in: path
required: true
description: the name of the path.
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PathConf'
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: path not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/paths/replace/{name}:
post:
operationId: configPathsReplace
tags: [Configuration]
summary: replaces all values of a path configuration.
description: all fields are optional.
parameters:
- name: name
in: path
required: true
description: the name of the path.
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PathConf'
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: path not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/paths/delete/{name}:
delete:
operationId: configPathsDelete
tags: [Configuration]
summary: removes a path configuration.
description: ''
parameters:
- name: name
in: path
required: true
description: the name of the path.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: path not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/hlsmuxers/list:
get:
operationId: hlsMuxersList
tags: [HLS]
summary: returns all HLS muxers.
description: ''
parameters:
- name: page
in: query
description: page number.
schema:
type: integer
default: 0
- name: itemsPerPage
in: query
description: items per page.
schema:
type: integer
default: 100
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/HLSMuxerList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/hlsmuxers/get/{name}:
get:
operationId: hlsMuxersGet
tags: [HLS]
summary: returns a HLS muxer.
description: ''
parameters:
- name: name
in: path
required: true
description: name of the muxer.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/HLSMuxer'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: muxer not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/paths/list:
get:
operationId: pathsList
tags: [Paths]
summary: returns all paths.
description: ''
parameters:
- name: page
in: query
description: page number.
schema:
type: integer
default: 0
- name: itemsPerPage
in: query
description: items per page.
schema:
type: integer
default: 100
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/PathList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/paths/get/{name}:
get:
operationId: pathsGet
tags: [Paths]
summary: returns a path.
description: ''
parameters:
- name: name
in: path
required: true
description: name of the path.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/Path'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: path not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspconns/list:
get:
operationId: rtspConnsList
tags: [RTSP]
summary: returns all RTSP connections.
description: ''
parameters:
- name: page
in: query
description: page number.
schema:
type: integer
default: 0
- name: itemsPerPage
in: query
description: items per page.
schema:
type: integer
default: 100
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RTSPConnList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspconns/get/{id}:
get:
operationId: rtspConnsGet
tags: [RTSP]
summary: returns a RTSP connection.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the connection.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RTSPConn'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: connection not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspsessions/list:
get:
operationId: rtspSessionsList
tags: [RTSP]
summary: returns all RTSP sessions.
description: ''
parameters:
- name: page
in: query
description: page number.
schema:
type: integer
default: 0
- name: itemsPerPage
in: query
description: items per page.
schema:
type: integer
default: 100
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RTSPSessionList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspsessions/get/{id}:
get:
operationId: rtspSessionsGet
tags: [RTSP]
summary: returns a RTSP session.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the connection.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RTSPSession'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: session not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspsessions/kick/{id}:
post:
operationId: rtspSessionsKick
tags: [RTSP]
summary: kicks out a RTSP session from the server.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the session.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: session not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspsconns/list:
get:
operationId: rtspsConnsList
tags: [RTSP]
summary: returns all RTSPS connections.
description: ''
parameters:
- name: page
in: query
description: page number.
schema:
type: integer
default: 0
- name: itemsPerPage
in: query
description: items per page.
schema:
type: integer
default: 100
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RTSPConnList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspsconns/get/{id}:
get:
operationId: rtspsConnsGet
tags: [RTSP]
summary: returns a RTSPS connection.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the connection.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RTSPConn'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: connection not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspssessions/list:
get:
operationId: rtspsSessionsList
tags: [RTSP]
summary: returns all RTSPS sessions.
description: ''
parameters:
- name: page
in: query
description: page number.
schema:
type: integer
default: 0
- name: itemsPerPage
in: query
description: items per page.
schema:
type: integer
default: 100
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RTSPSessionList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspssessions/get/{id}:
get:
operationId: rtspsSessionsGet
tags: [RTSP]
summary: returns a RTSPS session.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the connection.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RTSPSession'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: session not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspssessions/kick/{id}:
post:
operationId: rtspsSessionsKick
tags: [RTSP]
summary: kicks out a RTSPS session from the server.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the session.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: session not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtmpconns/list:
get:
operationId: rtmpConnsList
tags: [RTMP]
summary: returns all RTMP connections.
description: ''
parameters:
- name: page
in: query
description: page number.
schema:
type: integer
default: 0
- name: itemsPerPage
in: query
description: items per page.
schema:
type: integer
default: 100
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RTMPConnList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtmpconns/get/{id}:
get:
operationId: rtmpConnectionsGet
tags: [RTMP]
summary: returns a RTMP connection.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the connection.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RTMPConn'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: connection not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtmpconns/kick/{id}:
post:
operationId: rtmpConnsKick
tags: [RTMP]
summary: kicks out a RTMP connection from the server.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the connection.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: connection not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtmpsconns/list:
get:
operationId: rtmpsConnsList
tags: [RTMP]
summary: returns all RTMPS connections.
description: ''
parameters:
- name: page
in: query
description: page number.
schema:
type: integer
default: 0
- name: itemsPerPage
in: query
description: items per page.
schema:
type: integer
default: 100
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RTMPConnList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtmpsconns/get/{id}:
get:
operationId: rtmpsConnectionsGet
tags: [RTMP]
summary: returns a RTMPS connection.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the connection.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RTMPConn'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: connection not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtmpsconns/kick/{id}:
post:
operationId: rtmpsConnsKick
tags: [RTMP]
summary: kicks out a RTMPS connection from the server.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the connection.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: connection not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/srtconns/list:
get:
operationId: srtConnsList
tags: [SRT]
summary: returns all SRT connections.
description: ''
parameters:
- name: page
in: query
description: page number.
schema:
type: integer
default: 0
- name: itemsPerPage
in: query
description: items per page.
schema:
type: integer
default: 100
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/SRTConnList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/srtconns/get/{id}:
get:
operationId: srtConnsGet
tags: [SRT]
summary: returns a SRT connection.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the connection.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/SRTConn'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: connection not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/srtconns/kick/{id}:
post:
operationId: srtConnsKick
tags: [SRT]
summary: kicks out a SRT connection from the server.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the connection.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: connection not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/webrtcsessions/list:
get:
operationId: webrtcSessionsList
tags: [WebRTC]
summary: returns all WebRTC sessions.
description: ''
parameters:
- name: page
in: query
description: page number.
schema:
type: integer
default: 0
- name: itemsPerPage
in: query
description: items per page.
schema:
type: integer
default: 100
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/WebRTCSessionList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/webrtcsessions/get/{id}:
get:
operationId: webrtcSessionsGet
tags: [WebRTC]
summary: returns a WebRTC session.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the session.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/WebRTCSession'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: session not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/webrtcsessions/kick/{id}:
post:
operationId: webrtcSessionsKick
tags: [WebRTC]
summary: kicks out a WebRTC session from the server.
description: ''
parameters:
- name: id
in: path
required: true
description: ID of the session.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: session not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/recordings/list:
get:
operationId: recordingsList
tags: [Recordings]
summary: returns all recordings, splitted by path.
description: ''
parameters:
- name: page
in: query
description: page number.
schema:
type: integer
default: 0
- name: itemsPerPage
in: query
description: items per page.
schema:
type: integer
default: 100
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/RecordingList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/recordings/get/{name}:
get:
operationId: recordingsGet
tags: [Recordings]
summary: returns recordings of a path.
description: ''
parameters:
- name: name
in: path
required: true
description: name of the path.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/Recording'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: path not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/recordings/deletesegment:
delete:
operationId: recordingsDeleteSegment
tags: [Recordings]
summary: deletes a recording segment.
description: ''
parameters:
- name: path
in: query
required: true
description: path.
schema:
type: string
- name: start
in: query
required: true
description: starting date of the segment.
schema:
type: string
responses:
'200':
description: the request was successful.
content:
application/json:
schema:
$ref: '#/components/schemas/OK'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: connection not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
================================================
FILE: docker/ffmpeg-rpi.Dockerfile
================================================
#################################################################
FROM --platform=linux/amd64 scratch AS binaries
ADD binaries/mediamtx_*_linux_armv6.tar.gz /linux/arm/v6
ADD binaries/mediamtx_*_linux_armv7.tar.gz /linux/arm/v7
ADD binaries/mediamtx_*_linux_arm64.tar.gz /linux/arm64
#################################################################
FROM --platform=linux/arm/v7 debian:bullseye-slim AS base-arm-v7
# even though the base image is arm v7,
# Raspbian libraries and compilers provide arm v6 compatibility.
RUN apt update \
&& apt install -y wget gpg \
&& echo "deb http://archive.raspbian.org/raspbian bullseye main rpi firmware" > /etc/apt/sources.list \
&& echo "deb http://archive.raspberrypi.org/debian bullseye main" > /etc/apt/sources.list.d/raspi.list \
&& wget -O- https://archive.raspbian.org/raspbian.public.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/raspbian.gpg \
&& wget -O- https://archive.raspberrypi.org/debian/raspberrypi.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/raspberrypi.gpg \
&& rm -rf /var/lib/apt/lists/*
RUN apt update && apt install --reinstall -y \
libc6 \
libc-bin \
libstdc++6 \
&& rm -rf /var/lib/apt/lists/*
#################################################################
FROM --platform=linux/arm64 debian:bullseye-slim AS base-arm64
RUN apt update \
&& apt install -y wget gpg \
&& echo "deb http://archive.raspberrypi.org/debian bullseye main" > /etc/apt/sources.list.d/raspi.list \
&& wget -O- https://archive.raspberrypi.org/debian/raspberrypi.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/raspberrypi.gpg \
&& rm -rf /var/lib/apt/lists/*
#################################################################
FROM --platform=linux/amd64 scratch AS base
COPY --from=base-arm-v7 / /linux/arm/v6
COPY --from=base-arm-v7 / /linux/arm/v7
COPY --from=base-arm64 / /linux/arm64
#################################################################
FROM scratch
ARG TARGETPLATFORM
COPY --from=base /$TARGETPLATFORM /
RUN apt update \
&& apt install -y --no-install-recommends ffmpeg \
&& rm -rf /var/lib/apt/lists/*
COPY --from=binaries /$TARGETPLATFORM /
ENTRYPOINT [ "/mediamtx" ]
================================================
FILE: docker/ffmpeg.Dockerfile
================================================
#################################################################
FROM --platform=linux/amd64 scratch AS binaries
ADD binaries/mediamtx_*_linux_amd64.tar.gz /linux/amd64
ADD binaries/mediamtx_*_linux_armv6.tar.gz /linux/arm/v6
ADD binaries/mediamtx_*_linux_armv7.tar.gz /linux/arm/v7
ADD binaries/mediamtx_*_linux_arm64.tar.gz /linux/arm64
#################################################################
FROM alpine:3.22
RUN apk add --no-cache ffmpeg
ARG TARGETPLATFORM
COPY --from=binaries /$TARGETPLATFORM /
ENTRYPOINT [ "/mediamtx" ]
================================================
FILE: docker/rpi.Dockerfile
================================================
#################################################################
FROM --platform=linux/amd64 scratch AS binaries
ADD binaries/mediamtx_*_linux_armv6.tar.gz /linux/arm/v6
ADD binaries/mediamtx_*_linux_armv7.tar.gz /linux/arm/v7
ADD binaries/mediamtx_*_linux_arm64.tar.gz /linux/arm64
#################################################################
FROM --platform=linux/arm/v7 debian:bullseye-slim AS base-arm-v7
# even though the base image is arm v7,
# Raspbian libraries and compilers provide arm v6 compatibility.
RUN apt update \
&& apt install -y wget gpg \
&& echo "deb http://archive.raspbian.org/raspbian bullseye main rpi firmware" > /etc/apt/sources.list \
&& echo "deb http://archive.raspberrypi.org/debian bullseye main" > /etc/apt/sources.list.d/raspi.list \
&& wget -O- https://archive.raspbian.org/raspbian.public.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/raspbian.gpg \
&& wget -O- https://archive.raspberrypi.org/debian/raspberrypi.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/raspberrypi.gpg \
&& rm -rf /var/lib/apt/lists/*
RUN apt update && apt install --reinstall -y \
libc6 \
libc-bin \
libstdc++6 \
&& rm -rf /var/lib/apt/lists/*
#################################################################
FROM --platform=linux/arm64 debian:bullseye-slim AS base-arm64
RUN apt update \
&& apt install -y wget gpg \
&& echo "deb http://archive.raspberrypi.org/debian bullseye main" > /etc/apt/sources.list.d/raspi.list \
&& wget -O- https://archive.raspberrypi.org/debian/raspberrypi.gpg.key | gpg --dearmor -o /etc/apt/trusted.gpg.d/raspberrypi.gpg \
&& rm -rf /var/lib/apt/lists/*
#################################################################
FROM --platform=linux/amd64 scratch AS base
COPY --from=base-arm-v7 / /linux/arm/v6
COPY --from=base-arm-v7 / /linux/arm/v7
COPY --from=base-arm64 / /linux/arm64
#################################################################
FROM scratch
ARG TARGETPLATFORM
COPY --from=base /$TARGETPLATFORM /
COPY --from=binaries /$TARGETPLATFORM /
ENTRYPOINT [ "/mediamtx" ]
================================================
FILE: docker/standard.Dockerfile
================================================
#################################################################
FROM --platform=linux/amd64 scratch AS binaries
ADD binaries/mediamtx_*_linux_amd64.tar.gz /linux/amd64
ADD binaries/mediamtx_*_linux_armv6.tar.gz /linux/arm/v6
ADD binaries/mediamtx_*_linux_armv7.tar.gz /linux/arm/v7
ADD binaries/mediamtx_*_linux_arm64.tar.gz /linux/arm64
#################################################################
FROM scratch
ARG TARGETPLATFORM
COPY --from=binaries /$TARGETPLATFORM /
ENTRYPOINT [ "/mediamtx" ]
================================================
FILE: docs/1-kickoff/1-introduction.md
================================================
# Introduction
Welcome to the MediaMTX documentation!
_MediaMTX_ is a ready-to-use and zero-dependency live media server and media proxy. It has been conceived as a "media router" that routes media streams from one end to the other, with a focus on efficiency and portability.
Main features:
- [Publish](../2-publish/01-overview.md) live streams to the server with SRT, WebRTC, RTSP, RTMP, HLS, MPEG-TS, RTP, using FFmpeg, GStreamer, OBS Studio, Python , Golang, Unity, Web browsers, Raspberry Pi Cameras and more.
- [Read](../3-read/01-overview.md) live streams from the server with SRT, WebRTC, RTSP, RTMP, HLS, using FFmpeg, GStreamer, VLC, OBS Studio, Python , Golang, Unity, Web browsers and more.
- Streams are automatically converted from a protocol to another
- Serve several streams at once in separate paths
- Reload the configuration without disconnecting existing clients (hot reloading)
- [Serve always-available streams](../4-other/05-always-available.md) even when the publisher is offline
- [Record](../4-other/06-record.md) streams to disk in fMP4 or MPEG-TS format
- [Playback](../4-other/07-playback.md) recorded streams
- [Authenticate](../4-other/03-authentication.md) users with internal, HTTP or JWT authentication
- [Forward](../4-other/08-forward.md) streams to other servers
- [Proxy](../4-other/09-proxy.md) requests to other servers
- [Control](../4-other/18-control-api.md) the server through the Control API
- [Extract metrics](../4-other/19-metrics.md) from the server in a Prometheus-compatible format
- [Monitor performance](../4-other/20-performance.md) to investigate CPU and RAM consumption
- [Run hooks](../4-other/17-hooks.md) (external commands) when clients connect, disconnect, read or publish streams
- Compatible with Linux, Windows and macOS, does not require any dependency or interpreter, it's a single executable
Use the menu to navigate through the documentation.
================================================
FILE: docs/1-kickoff/2-install.md
================================================
# Install
There are several installation methods available:
- [Standalone binary](#standalone-binary): use this if you are running Windows, macOS or you just want to try out _MediaMTX_.
- [Docker image](#docker-image): use this if you want to run _MediaMTX_ in an isolated and deterministic way. This is recommended for production environments.
- [Arch Linux package](#arch-linux-package): use this if you are running Arch Linux.
- [FreeBSD package](#freebsd-package): use this if you are running FreeBSD.
- [OpenWrt binary](#openwrt-binary): use this if you are running OpenWrt.
## Standalone binary
1. Visit the [Releases page](https://github.com/bluenviron/mediamtx/releases) on GitHub, download and extract a standalone binary that corresponds to your operating system and architecture (example: `mediamtx_{version_tag}_linux_amd64.tar.gz`).
2. Start the server by double clicking on `mediamtx` (`mediamtx.exe` on Windows) or writing in the terminal:
```sh
./mediamtx
```
## Docker image
Download and launch the `bluenviron/mediamtx:1` image with the following environment variables and ports:
```sh
docker run --rm -it \
-e MTX_RTSPTRANSPORTS=tcp \
-e MTX_WEBRTCADDITIONALHOSTS=192.168.x.x \
-p 8554:8554 \
-p 1935:1935 \
-p 8888:8888 \
-p 8889:8889 \
-p 8890:8890/udp \
-p 8189:8189/udp \
bluenviron/mediamtx:1
```
Fill the `MTX_WEBRTCADDITIONALHOSTS` environment variable with the IP that will be used to connect to the server.
The `MTX_RTSPTRANSPORTS=tcp` environment variable is meant to disable the UDP transport protocol of the RTSP server (which requires the real IP address and port of incoming UDP packets, that are sometimes replaced by the Docker network stack). If you want to use it, you need to bypass the Docker network stack through the `--network=host` flag (which is not compatible with Windows, macOS and Kubernetes):
```sh
docker run --rm -it --network=host bluenviron/mediamtx:1
```
There are four image variants:
| name | FFmpeg included | RPI Camera support |
| -------------------------------- | ------------------ | ------------------ |
| bluenviron/mediamtx:1 | :x: | :x: |
| bluenviron/mediamtx:1-ffmpeg | :heavy_check_mark: | :x: |
| bluenviron/mediamtx:1-rpi | :x: | :heavy_check_mark: |
| bluenviron/mediamtx:1-ffmpeg-rpi | :heavy_check_mark: | :heavy_check_mark: |
The `1` tag corresponds to the latest `1.x.x` release, that should guarantee backward compatibility when upgrading. It is also possible to bind the image to a specific release, by using the release name as tag (`bluenviron/mediamtx:{docker_version_tag}`).
The base image does not contain any utility, in order to minimize size and frequency of updates. If you need additional software (like curl, wget, GStreamer), you can build a custom image by creating a file named `Dockerfile` with this content:
```Dockerfile
FROM bluenviron/mediamtx:1 AS mediamtx
FROM ubuntu:24.04
COPY --from=mediamtx /mediamtx /
COPY --from=mediamtx /mediamtx.yml /
# add anything you need.
RUN apt update && apt install -y \
gstreamer1.0-tools
ENTRYPOINT [ "/mediamtx" ]
```
And then build it:
```sh
docker build . -t my-mediamtx
```
In particular, the custom image is using the official _MediaMTX_ image as a base stage, and then adds a Linux-based operating system on top of it. Since _MediaMTX_ binaries are not tied to a specific Linux distribution or version, you can use anything you like.
## Arch Linux package
If you are running the Arch Linux distribution, launch:
```sh
git clone https://aur.archlinux.org/mediamtx.git
cd mediamtx
makepkg -si
```
## FreeBSD package
Available via ports tree or using packages (2025Q2 and later) as listed below:
```sh
cd /usr/ports/multimedia/mediamtx && make install clean
pkg install mediamtx
```
## OpenWrt binary
If the architecture of the OpenWrt device is amd64, armv6, armv7 or arm64, use the [standalone binary method](#standalone-binary) and download a Linux binary that corresponds to your architecture.
Otherwise, [compile the server from source](../6-misc/1-compile.md).
================================================
FILE: docs/1-kickoff/3-upgrade.md
================================================
# Upgrade
If you have an existing _MediaMTX_ installation, you can upgrade it to the latest version. The procedure depends on how _MediaMTX_ was installed.
## Standalone binary
The standalone binary comes with an upgrade utility that can be launched with:
```sh
./mediamtx --upgrade
```
This will replace the _MediaMTX_ executable with its latest version. Privileges to write to the executable location are required.
## Docker image
Stop and remove the container:
```sh
docker stop id-of-mediamtx-container
docker rm id-of-mediamtx-container
```
Remove the _MediaMTX_ image from cache:
```sh
docker rm bluenviron/mediamtx:1
```
Then recreate the container as described in [Install](2-install.md#docker-image).
## Arch Linux package
Repeat the installation procedure.
## FreeBSD package
Repeat the installation procedure.
## OpenWrt binary
If the architecture of the OpenWrt device is amd64, armv6, armv7 or arm64, you can use the standalone binary method.
Otherwise, recompile the server from source.
================================================
FILE: docs/1-kickoff/4-basic-usage.md
================================================
# Basic usage
1. [Publish](../2-publish/01-overview.md) a stream. For instance, you can publish a stream from a MP4 file with _FFmpeg_:
```sh
ffmpeg -re -stream_loop -1 -i file.mp4 -c copy \
-f rtsp rtsp://localhost:8554/mystream
```
or _GStreamer_:
```sh
gst-launch-1.0 rtspclientsink name=s location=rtsp://localhost:8554/mystream filesrc location=file.mp4 \
! qtdemux name=d d.video_0 ! queue ! s.sink_0 d.audio_0 ! queue ! s.sink_1
```
2. [Read](../3-read/01-overview.md) the stream. For instance, you can read the stream with _VLC_:
```sh
vlc --network-caching=50 rtsp://localhost:8554/mystream
```
or _GStreamer_:
```sh
gst-play-1.0 rtsp://localhost:8554/mystream
```
or _FFmpeg_:
```sh
ffmpeg -i rtsp://localhost:8554/mystream -c copy output.mp4
```
================================================
FILE: docs/1-kickoff/index.md
================================================
# Kickoff
================================================
FILE: docs/2-publish/01-overview.md
================================================
# Publish a stream
Live streams can be published to the server with the following protocols and codecs:
| protocol | variants | codecs |
| ---------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [SRT clients](02-srt-clients.md) | | **Video**: H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3<br/>**Other**: KLV |
| [SRT cameras and servers](03-srt-cameras-and-servers.md) | | **Video**: H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3<br/>**Other**: KLV |
| [WebRTC clients](04-webrtc-clients.md) | WHIP | **Video**: AV1, VP9, VP8, H265, H264<br/>**Audio**: Opus, G722, G711 (PCMA, PCMU) |
| [WebRTC servers](05-webrtc-servers.md) | WHEP | **Video**: AV1, VP9, VP8, H265, H264<br/>**Audio**: Opus, G722, G711 (PCMA, PCMU) |
| [RTSP clients](06-rtsp-clients.md) | UDP, TCP, RTSPS | **Video**: AV1, VP9, VP8, H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video, MJPEG<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3, G726, G722, G711 (PCMA, PCMU), LPCM<br/>**Other**: KLV, MPEG-TS, any RTP-compatible codec |
| [RTSP cameras and servers](07-rtsp-cameras-and-servers.md) | UDP, UDP-Multicast, TCP, RTSPS | **Video**: AV1, VP9, VP8, H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video, MJPEG<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3, G726, G722, G711 (PCMA, PCMU), LPCM<br/>**Other**: KLV, MPEG-TS, any RTP-compatible codec |
| [RTMP clients](08-rtmp-clients.md) | RTMP, RTMPS, Enhanced RTMP | **Video**: AV1, VP9, H265, H264<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3, G711 (PCMA, PCMU), LPCM |
| [RTMP cameras and servers](09-rtmp-cameras-and-servers.md) | RTMP, RTMPS, Enhanced RTMP | **Video**: AV1, VP9, H265, H264<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3, G711 (PCMA, PCMU), LPCM |
| [HLS cameras and servers](10-hls-cameras-and-servers.md) | Low-Latency HLS, MP4-based HLS, legacy HLS | **Video**: AV1, VP9, H265, H264<br/>**Audio**: Opus, MPEG-4 Audio (AAC) |
| [MPEG-TS](11-mpeg-ts.md) | MPEG-TS over UDP, MPEG-TS over Unix socket | **Video**: H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3<br/>**Other**: KLV |
| [RTP](12-rtp.md) | RTP over UDP | **Video**: AV1, VP9, VP8, H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video, M-JPEG<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3, G726, G722, G711 (PCMA, PCMU), LPCM<br/>**Other**: KLV, MPEG-TS, any RTP-compatible codec |
We provide instructions for publishing with the following devices:
- [Raspberry Pi Cameras](13-raspberry-pi-cameras.md)
- [Generic webcams](14-generic-webcams.md)
We provide instructions for publishing with the following software:
- [FFmpeg](15-ffmpeg.md)
- [GStreamer](16-gstreamer.md)
- [OBS Studio](17-obs-studio.md)
- [Python and OpenCV](18-python-opencv.md)
- [Golang](19-golang.md)
- [Unity](20-unity.md)
- [Web browsers](21-web-browsers.md)
================================================
FILE: docs/2-publish/02-srt-clients.md
================================================
# SRT clients
SRT is a protocol that allows to publish and read live data stream, providing encryption, integrity and a retransmission mechanism. It is usually used to transfer media streams encoded with MPEG-TS. In order to publish a stream to the server with the SRT protocol, use this URL:
```
srt://localhost:8890?streamid=publish:mystream&pkt_size=1316
```
Replace `mystream` with any name you want. The resulting stream will be available on path `/mystream`.
If you need to use the standard stream ID syntax instead of the custom one in use by this server, read [Standard stream ID syntax](../4-other/21-srt-specific-features.md#standard-stream-id-syntax).
If you want to publish a stream by using a client in listening mode (i.e. with `mode=listener` appended to the URL), read the next section.
Some clients that can publish with SRT are [FFmpeg](15-ffmpeg.md), [GStreamer](16-gstreamer.md), [OBS Studio](17-obs-studio.md).
================================================
FILE: docs/2-publish/03-srt-cameras-and-servers.md
================================================
# SRT cameras and servers
In order to ingest a SRT stream from a remote server, camera or client in listening mode (i.e. with `mode=listener` appended to the URL), add the corresponding URL into the `source` parameter of a path:
```yml
paths:
proxied:
# url of the source stream, in the format srt://host:port?streamid=streamid&other_parameters
source: srt://original-url
```
================================================
FILE: docs/2-publish/04-webrtc-clients.md
================================================
# WebRTC clients
WebRTC is an API that makes use of a set of protocols and methods to connect two clients together and allow them to exchange live media or data streams. You can publish a stream with WebRTC and a web browser by visiting:
```
http://localhost:8889/mystream/publish
```
The resulting stream will be available on path `/mystream`.
WHIP is a WebRTC extension that allows to publish streams by using a URL, without passing through a web page. This allows to use WebRTC as a general purpose streaming protocol. If you are using a software that supports WHIP (for instance, latest versions of OBS Studio), you can publish a stream to the server by using this URL:
```
http://localhost:8889/mystream/whip
```
Be aware that not all browsers can read any codec, check [Supported browsers](../4-other/22-webrtc-specific-features.md#supported-browsers).
Depending on the network it might be difficult to establish a connection between server and clients, read [Solving WebRTC connectivity issues](../4-other/22-webrtc-specific-features.md#solving-webrtc-connectivity-issues).
Some clients that can publish with WebRTC and WHIP are [FFmpeg](15-ffmpeg.md), [GStreamer](16-gstreamer.md), [OBS Studio](17-obs-studio.md), [Unity](20-unity.md) and [Web browsers](21-web-browsers.md).
================================================
FILE: docs/2-publish/05-webrtc-servers.md
================================================
# WebRTC servers
In order to ingest a WebRTC stream from a remote server, add the corresponding WHEP URL into the `source` parameter of a path:
```yml
paths:
proxied:
# url of the source stream, in the format whep://host:port/path (HTTP) or wheps:// (HTTPS)
source: wheps://host:port/path
```
If the remote server is a _MediaMTX_ instance, remember to add a `/whep` suffix after the stream name, since in _MediaMTX_ [it's part of the WHEP URL](../3-read/03-webrtc.md):
```yml
paths:
proxied:
source: whep://host:port/mystream/whep
```
================================================
FILE: docs/2-publish/06-rtsp-clients.md
================================================
# RTSP clients
RTSP is a protocol that allows to publish and read streams. It supports several underlying transport protocols and encryption. In order to publish a stream to the server with the RTSP protocol, use this URL:
```
rtsp://localhost:8554/mystream
```
The resulting stream will be available on path `/mystream`.
Some clients that can publish with RTSP are [FFmpeg](15-ffmpeg.md), [GStreamer](16-gstreamer.md), [OBS Studio](17-obs-studio.md), [Python and OpenCV](18-python-opencv.md).
Advanced RTSP features and settings are described in [RTSP-specific features](../4-other/23-rtsp-specific-features.md).
## MPEG-TS inside RTSP
Some RTSP clients encode tracks with MPEG-TS before sending them to the server, causing the server to see a single "MPEG-TS" track, and preventing track conversion from a protocol to another.
It's possible to automatically demux these MPEG-TS-encoded streams, by toggling `rtspDemuxMpegts`:
```yml
pathDefaults:
# Demux MPEG-TS over RTSP into elementary streams.
# When enabled, RTSP publishers sending MP2T/90000 will be demultiplexed
# and their elementary streams (H.264, H.265, AAC, etc.) exposed as native tracks.
# This allows HLS, WebRTC, and other outputs to work transparently with MPEG-TS sources.
rtspDemuxMpegts: true
```
================================================
FILE: docs/2-publish/07-rtsp-cameras-and-servers.md
================================================
# RTSP cameras and servers
Most IP cameras expose their video stream by using a RTSP server that is embedded into the camera itself. In particular, cameras that are compliant with ONVIF profile S or T meet this requirement. You can use _MediaMTX_ to connect to one or several existing RTSP servers and read their media streams:
```yml
paths:
proxied:
# url of the source stream, in the format rtsp://user:pass@host:port/path
source: rtsp://original-url
```
The resulting stream will be available on path `/proxied`.
It is possible to tune the connection by using some additional parameters:
```yml
paths:
proxied:
# url of the source stream, in the format rtsp://user:pass@host:port/path
source: rtsp://original-url
# Transport protocol used to pull the stream. available values are "automatic", "udp", "multicast", "tcp".
rtspTransport: automatic
# Support sources that don't provide server ports or use random server ports. This is a security issue
# and must be used only when interacting with sources that require it.
rtspAnyPort: no
# Range header to send to the source, in order to start streaming from the specified offset.
# available values:
# * clock: Absolute time
# * npt: Normal Play Time
# * smpte: SMPTE timestamps relative to the start of the recording
rtspRangeType:
# Available values:
# * clock: UTC ISO 8601 combined date and time string, e.g. 20230812T120000Z
# * npt: duration such as "300ms", "1.5m" or "2h45m", valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
# * smpte: duration such as "300ms", "1.5m" or "2h45m", valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h"
rtspRangeStart:
# Size of the UDP buffer of the RTSP client.
# This can be increased to mitigate packet losses.
# It defaults to the default value of the operating system.
rtspUDPReadBufferSize: 0
# Range of ports used as source port in outgoing UDP packets.
rtspUDPSourcePortRange: [10000, 65535]
```
All available parameters are listed in the [configuration file](../5-references/1-configuration-file.md).
Advanced RTSP features and settings are described in [RTSP-specific features](../4-other/23-rtsp-specific-features.md).
================================================
FILE: docs/2-publish/08-rtmp-clients.md
================================================
# RTMP clients
RTMP is a protocol that allows to read and publish streams. It supports encryption, read [RTMP-specific features](../4-other/24-rtmp-specific-features.md). Streams can be published to the server by using the URL:
```
rtmp://localhost/mystream
```
The resulting stream will be available on path `/mystream`.
Some clients that can publish with RTMP are [FFmpeg](15-ffmpeg.md), [GStreamer](16-gstreamer.md), [OBS Studio](17-obs-studio.md).
================================================
FILE: docs/2-publish/09-rtmp-cameras-and-servers.md
================================================
# RTMP cameras and servers
You can use _MediaMTX_ to connect to one or several existing RTMP servers and read their media streams:
```yml
paths:
proxied:
# url of the source stream, in the format rtmp://user:pass@host:port/path
source: rtmp://original-url
```
The resulting stream will be available on path `/proxied`.
================================================
FILE: docs/2-publish/10-hls-cameras-and-servers.md
================================================
# HLS cameras and servers
HLS is a streaming protocol that works by splitting streams into segments, and by serving these segments and a playlist with the HTTP protocol. You can use _MediaMTX_ to connect to one or several existing HLS servers and read their media streams:
```yml
paths:
proxied:
# url of the playlist of the stream, in the format http://user:pass@host:port/path
source: http://original-url/stream/index.m3u8
```
The resulting stream will be available on path `/proxied`.
================================================
FILE: docs/2-publish/11-mpeg-ts.md
================================================
# MPEG-TS
The server supports ingesting MPEG-TS streams, shipped in two different ways (UDP packets or Unix sockets).
In order to read a UDP MPEG-TS stream, edit `mediamtx.yml` and replace everything inside section `paths` with the following content:
```yml
paths:
mypath:
source: udp+mpegts://238.0.0.1:1234
```
Where `238.0.0.1` is the IP for listening packets, in this case a multicast IP.
If the listening IP is a multicast IP, _MediaMTX_ will listen for incoming packets on the default multicast interface, picked by the operating system. It is possible to specify the interface manually by using the `interface` parameter:
```yml
paths:
mypath:
source: udp+mpegts://238.0.0.1:1234?interface=eth0
```
It is possible to restrict who can send packets by using the `source` parameter:
```yml
paths:
mypath:
source: udp+mpegts://0.0.0.0:1234?source=192.168.3.5
```
Some clients that can publish with UDP and MPEG-TS are [FFmpeg](15-ffmpeg.md) and [GStreamer](16-gstreamer.md).
Unix sockets are more efficient than UDP packets and can be used as transport by specifying the `unix+mpegts` scheme:
```yml
paths:
mypath:
source: unix+mpegts:///tmp/socket.sock
```
================================================
FILE: docs/2-publish/12-rtp.md
================================================
# RTP
The server supports ingesting RTP streams, transmitted with UDP packets.
In order to read a UDP RTP stream, edit `mediamtx.yml` and replace everything inside section `paths` with the following content:
```yml
paths:
mypath:
source: udp+rtp://238.0.0.1:1234
rtpSDP: |
v=0
o=- 123456789 123456789 IN IP4 192.168.1.100
s=H264 Video Stream
c=IN IP4 192.168.1.100
t=0 0
m=video 5004 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 profile-level-id=42e01e;packetization-mode=1;sprop-parameter-sets=Z0LAHtkDxWhAAAADAEAAAAwDxYuS,aMuMsg==
```
`rtpSDP` must contain a valid SDP, that is a description of the RTP session.
Some clients that can publish with UDP and MPEG-TS are [FFmpeg](15-ffmpeg.md) and [GStreamer](16-gstreamer.md).
================================================
FILE: docs/2-publish/13-raspberry-pi-cameras.md
================================================
# Raspberry Pi Cameras
_MediaMTX_ natively supports most Raspberry Pi Camera models, enabling high-quality and low-latency video streaming from the camera to any user, for any purpose. There are some additional requirements:
1. The server must run on a Raspberry Pi, with one of the following operating systems:
- Raspberry Pi OS Trixie
- Raspberry Pi OS Bookworm
- Raspberry Pi OS Bullseye
Both 32-bit and 64-bit architectures are supported.
2. If you are using Raspberry Pi OS Bullseye, make sure that the legacy camera stack is disabled. Type `sudo raspi-config`, then go to `Interfacing options`, `enable/disable legacy camera support`, choose `no`. Reboot the system.
The setup procedure depends on whether you want to run the server outside or inside Docker:
- If you want to run the standard (non-Dockerized) version of the server:
1. Download the server executable. If you're using 64-bit version of the operative system, make sure to pick the `arm64` variant.
2. Edit `mediamtx.yml` and replace everything inside section `paths` with the following content:
```yml
paths:
cam:
source: rpiCamera
```
The resulting stream will be available on path `/cam`.
- If you want to run the server inside Docker, you need to use the `1-rpi` image and launch the container with some additional flags:
```sh
docker run --rm -it \
--network=host \
--privileged \
--tmpfs /dev/shm:exec \
-v /run/udev:/run/udev:ro \
-e MTX_PATHS_CAM_SOURCE=rpiCamera \
bluenviron/mediamtx:1-rpi
```
The Raspberry Pi Camera can be controlled through a wide range of parameters, that are listed in the [configuration file](../5-references/1-configuration-file.md).
Be aware that cameras that require a custom `libcamera` (like some ArduCam products) are not compatible with precompiled binaries and Docker images of _MediaMTX_, since these come with a bundled `libcamera`. If you want to use a custom one, you need to [compile from source](../6-misc/1-compile.md#custom-libcamera).
## Adding audio
In order to add audio from a USB microphone, install GStreamer and alsa-utils:
```sh
sudo apt install -y gstreamer1.0-tools gstreamer1.0-rtsp gstreamer1.0-alsa alsa-utils
```
list available audio cards with:
```sh
arecord -L
```
Sample output:
```
surround51:CARD=ICH5,DEV=0
Intel ICH5, Intel ICH5
5.1 Surround output to Front, Center, Rear and Subwoofer speakers
default:CARD=U0x46d0x809
USB Device 0x46d:0x809, USB Audio
Default Audio Device
```
Find the audio card of the microphone and take note of its name, for instance `default:CARD=U0x46d0x809`. Then create a new path that takes the video stream from the camera and audio from the microphone:
```yml
paths:
cam:
source: rpiCamera
cam_with_audio:
runOnInit: >
gst-launch-1.0
rtspclientsink name=s location=rtsp://localhost:$RTSP_PORT/cam_with_audio
rtspsrc location=rtsp://127.0.0.1:$RTSP_PORT/cam latency=0 ! rtph264depay ! s.
alsasrc device=default:CARD=U0x46d0x809 ! opusenc bitrate=16000 ! s.
runOnInitRestart: yes
```
The resulting stream will be available on path `/cam_with_audio`.
## Secondary stream
It is possible to enable a secondary stream from the same camera, with a different resolution, FPS and codec. Configuration is the same of a primary stream, with `rpiCameraSecondary` set to `true` and parameters adjusted accordingly:
```yml
paths:
# primary stream
rpi:
source: rpiCamera
# Width of frames.
rpiCameraWidth: 1920
# Height of frames.
rpiCameraHeight: 1080
# FPS.
rpiCameraFPS: 30
# secondary stream
secondary:
source: rpiCamera
# This is a secondary stream.
rpiCameraSecondary: true
# Width of frames.
rpiCameraWidth: 640
# Height of frames.
rpiCameraHeight: 480
# FPS.
rpiCameraFPS: 10
# Codec. in case of secondary streams, it defaults to M-JPEG.
rpiCameraCodec: auto
# JPEG quality.
rpiCameraMJPEGQuality: 60
```
The secondary stream will be available on path `/secondary`.
================================================
FILE: docs/2-publish/14-generic-webcams.md
================================================
# Generic webcams
If the operating system is Linux, edit `mediamtx.yml` and replace everything inside section `paths` with the following content:
```yml
paths:
cam:
runOnInit: ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 -pix_fmt yuv420p -preset ultrafast -b:v 600k -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH
runOnInitRestart: yes
```
If the operating system is Windows:
```yml
paths:
cam:
runOnInit: ffmpeg -f dshow -i video="USB2.0 HD UVC WebCam" -c:v libx264 -pix_fmt yuv420p -preset ultrafast -b:v 600k -f rtsp rtsp://localhost:$RTSP_PORT/$MTX_PATH
runOnInitRestart: yes
```
Where `USB2.0 HD UVC WebCam` is the name of a webcam, that can be obtained with:
```sh
ffmpeg -list_devices true -f dshow -i dummy
```
The resulting stream will be available on path `/cam`.
================================================
FILE: docs/2-publish/15-ffmpeg.md
================================================
# FFmpeg
FFmpeg can publish a stream to the server in several ways. The recommended one consists in publishing with RTSP.
## FFmpeg and RTSP
```sh
ffmpeg -re -stream_loop -1 -i file.mp4 -c copy -f rtsp rtsp://localhost:8554/mystream
```
The resulting stream will be available on path `/mystream`.
## FFmpeg and RTMP
```sh
ffmpeg -re -stream_loop -1 -i file.mp4 -c copy -f flv rtmp://localhost:1935/mystream
```
## FFmpeg and MPEG-TS over UDP
In _MediaMTX_ configuration, add a path with `source: udp+mpegts://238.0.0.1:1234`. Then:
```sh
ffmpeg -re -stream_loop -1 -i file.mp4 -c copy -f mpegts 'udp://238.0.0.1:1234?pkt_size=1316'
```
## FFmpeg and MPEG-TS over Unix socket
In _MediaMTX_ configuration, add a path with `source: unix+mpegts:///tmp/socket.sock`. Then:
```sh
ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
-c:v libx264 -pix_fmt yuv420p -preset ultrafast -b:v 600k \
-f mpegts unix:/tmp/socket.sock
```
## FFmpeg and RTP over UDP
In _MediaMTX_ configuration, add a path with `source: udp+rtp://238.0.0.1:1234` and a valid `rtpSDP` (read [RTP](12-rtp.md)). Then:
```sh
ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
-c:v libx264 -pix_fmt yuv420p -preset ultrafast -b:v 600k \
-f rtp udp://238.0.0.1:1234?pkt_size=1316
```
## FFmpeg and SRT
```sh
ffmpeg -re -stream_loop -1 -i file.mp4 -c copy -f mpegts 'srt://localhost:8890?streamid=publish:stream&pkt_size=1316'
```
## FFmpeg and WebRTC
```sh
ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 \
-f lavfi -i "sine=frequency=1000:sample_rate=48000" \
-c:v libx264 -pix_fmt yuv420p -preset ultrafast -b:v 600k \
-c:a libopus -ar 48000 -ac 2 -b:a 128k \
-f whip http://localhost:8889/stream/whip
```
WARNING: in case of FFmpeg 8.0, a video track and an audio track must both be present.
================================================
FILE: docs/2-publish/16-gstreamer.md
================================================
# GStreamer
GStreamer can publish a stream to the server in several ways. The recommended one consists in publishing with RTSP.
## GStreamer and RTSP
```sh
gst-launch-1.0 rtspclientsink name=s location=rtsp://localhost:8554/mystream \
filesrc location=file.mp4 ! qtdemux name=d \
d.video_0 ! queue ! s.sink_0 \
d.audio_0 ! queue ! s.sink_1
```
If the stream is video only:
```sh
gst-launch-1.0 filesrc location=file.mp4 ! qtdemux name=d \
d.video_0 ! rtspclientsink location=rtsp://localhost:8554/mystream
```
The resulting stream will be available on path `/mystream`.
For advanced options, read [RTSP-specific features](../4-other/23-rtsp-specific-features.md).
## GStreamer and RTMP
```sh
gst-launch-1.0 -v flvmux name=mux ! rtmpsink location=rtmp://localhost/stream \
videotestsrc ! video/x-raw,width=1280,height=720,format=I420 ! x264enc speed-preset=ultrafast bitrate=3000 key-int-max=60 ! video/x-h264,profile=high ! mux. \
audiotestsrc ! audioconvert ! avenc_aac ! mux.
```
## GStreamer and MPEG-TS over UDP
```sh
gst-launch-1.0 -v mpegtsmux name=mux alignment=1 ! udpsink host=238.0.0.1 port=1234 \
videotestsrc ! video/x-raw,width=1280,height=720,format=I420 ! x264enc speed-preset=ultrafast bitrate=3000 key-int-max=60 ! video/x-h264,profile=high ! mux. \
audiotestsrc ! audioconvert ! avenc_aac ! mux.
```
For advanced options, read [RTSP-specific features](../4-other/23-rtsp-specific-features.md).
## GStreamer and WebRTC
Make sure that GStreamer version is at least 1.22, and that if the codec is H264, the profile is baseline. Use the `whipclientsink` element:
```sh
gst-launch-1.0 videotestsrc \
! video/x-raw,width=1920,height=1080,format=I420 \
! x264enc speed-preset=ultrafast bitrate=2000 \
! video/x-h264,profile=baseline \
! whipclientsink signaller::whip-endpoint=http://localhost:8889/mystream/whip
```
================================================
FILE: docs/2-publish/17-obs-studio.md
================================================
# OBS Studio
OBS Studio can publish streams to the server in several ways. The recommended one consists in publishing with RTMP.
## OBS Studio and RTMP
In `Settings -> Stream` (or in the Auto-configuration Wizard), use the following parameters:
- Service: `Custom...`
- Server: `rtmp://localhost/mystream`
- Stream key: (empty)
Save the configuration and click `Start streaming`.
The resulting stream will be available on path `/mystream`.
If you want to generate a stream that can be read with WebRTC, open `Settings -> Output -> Recording` and use the following parameters:
- FFmpeg output type: `Output to URL`
- File path or URL: `rtsp://localhost:8554/mystream`
- Container format: `rtsp`
- Check `show all codecs (even if potentially incompatible)`
- Video encoder: `h264_nvenc (libx264)`
- Video encoder settings (if any): `bf=0`
- Audio track: `1`
- Audio encoder: `libopus`
Then use the button `Start Recording` (instead of `Start Streaming`) to start streaming.
## OBS Studio and RTMP, multitrack video
OBS Studio can publish multiple video tracks or renditions at once (simulcast). Make sure that the OBS Studio version is ≥ 31.0.0. Open `Settings -> Stream` and use the following parameters:
- Service: `Custom...`
- Server: `rtmp://localhost/mystream`
- Stream key: (empty)
- Turn on `Enable Multitrack Video`
- Leave `Maximum Streaming Bandwidth` and `Maximum Video Tracks` to `Auto`
- Turn on `Enable Config Override`
- Fill `Config Override (JSON)` with the following text:
```json
{
"encoder_configurations": [
{
"type": "obs_x264",
"width": 1920,
"height": 1080,
"framerate": {
"numerator": 30,
"denominator": 1
},
"settings": {
"rate_control": "CBR",
"bitrate": 6000,
"keyint_sec": 2,
"preset": "veryfast",
"profile": "high",
"tune": "zerolatency"
},
"canvas_index": 0
},
{
"type": "obs_x264",
"width": 640,
"height": 480,
"framerate": {
"numerator": 30,
"denominator": 1
},
"settings": {
"rate_control": "CBR",
"bitrate": 3000,
"keyint_sec": 2,
"preset": "veryfast",
"profile": "main",
"tune": "zerolatency"
},
"canvas_index": 0
}
],
"audio_configurations": {
"live": [
{
"codec": "ffmpeg_aac",
"track_id": 1,
"channels": 2,
"settings": {
"bitrate": 160
}
}
]
}
}
```
This can be adjusted according to specific needs. In particular, the `type` field is used to set the video encoder, and these are the available parameters:
- `obs_nvenc_av1_tex`: NVIDIA NVENC AV1
- `obs_nvenc_hevc_tex`: NVIDIA NVENC H265
- `obs_nvenc_h264_tex`: NVIDIA NVENC H264
- `av1_texture_amf`: AMD AV1
- `h265_texture_amf`: AMD H265
- `h264_texture_amf`: AMD H264
- `obs_qsv11_av1`: QuickSync AV1
- `obs_qsv11_v2`: QuickSync H264
- `obs_x264`: software H264
Save the configuration and click `Start streaming`.
The resulting stream will be available on path `/mystream`.
## OBS Studio and WebRTC
Recent versions of OBS Studio can also publish streams to the server with the [WebRTC / WHIP protocol](04-webrtc-clients.md) Use the following parameters:
- Service: `WHIP`
- Server: `http://localhost:8889/mystream/whip`
Save the configuration and click `Start streaming`.
The resulting stream will be available on path `/mystream`.
## OBS Studio and WebRTC, multitrack video
OBS Studio can publish multiple video tracks or renditions at once (simulcast) with WebRTC / WHIP too. Make sure that the OBS Studio version is ≥ 32.1.0. Open `Settings -> Stream` and use the following parameters:
- Service: `WHIP`
- Server: `http://localhost:8889/mystream/whip`
- Simulcast, Total Layers: `2` (or greater)
Currently it's not possible to change resolution or bitrate (or canvas) of renditions, since quality of secondary renditions is hardcoded as a percentage of the main one. You can find details on the [OBS documentation](https://obsproject.com/kb/whip-streaming-guide).
Save the configuration and click `Start streaming`.
The resulting stream will be available on path `/mystream`.
================================================
FILE: docs/2-publish/18-python-opencv.md
================================================
# Python and OpenCV
Python-based software can publish streams to the server with the OpenCV library and its GStreamer plugin, acting as a [RTSP client](06-rtsp-clients.md). OpenCV must be compiled with support for GStreamer, by following this procedure:
```sh
sudo apt install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-ugly gstreamer1.0-rtsp python3-dev python3-numpy
git clone --depth=1 -b 4.5.4 https://github.com/opencv/opencv
cd opencv
mkdir build && cd build
cmake -D CMAKE_INSTALL_PREFIX=/usr -D WITH_GSTREAMER=ON ..
make -j$(nproc)
sudo make install
```
You can check that OpenCV has been installed correctly by running:
```sh
python3 -c 'import cv2; print(cv2.getBuildInformation())'
```
Check that the output contains `GStreamer: YES`.
Videos can then be published with `cv2.VideoWriter`:
```python
from datetime import datetime
from time import sleep, time
import cv2
import numpy as np
fps = 15
width = 800
height = 600
colors = [
(0, 0, 255),
(255, 0, 0),
(0, 255, 0),
]
out = cv2.VideoWriter('appsrc ! videoconvert' + \
' ! video/x-raw,format=I420' + \
' ! x264enc speed-preset=ultrafast bitrate=600 key-int-max=' + str(fps * 2) + \
' ! video/x-h264,profile=baseline' + \
' ! rtspclientsink location=rtsp://localhost:8554/mystream',
cv2.CAP_GSTREAMER, 0, fps, (width, height), True)
if not out.isOpened():
raise Exception("can't open video writer")
curcolor = 0
start = time()
while True:
frame = np.zeros((height, width, 3), np.uint8)
# create a rectangle
color = colors[curcolor]
curcolor += 1
curcolor %= len(colors)
for y in range(0, int(frame.shape[0] / 2)):
for x in range(0, int(frame.shape[1] / 2)):
frame[y][x] = color
out.write(frame)
print("%s frame written to the server" % datetime.now())
now = time()
diff = (1 / fps) - now - start
if diff > 0:
sleep(diff)
start = now
```
The resulting stream will be available on path `/mystream`.
================================================
FILE: docs/2-publish/19-golang.md
================================================
# Golang
You can publish a stream to the server by using the Go programming language and the following libraries:
- [gortsplib](https://github.com/bluenviron/gortsplib) to publish with RTSP.
- [gortmplib](https://github.com/bluenviron/gortmplib) to publish with RTMP.
Both powers _MediaMTX_ itself. In the repositories of these projects there are several examples on how to connect to a server and push data.
================================================
FILE: docs/2-publish/20-unity.md
================================================
# Unity
Software written with the Unity Engine can publish a stream to the server by using the [WebRTC protocol](04-webrtc-clients.md).
Create a new Unity project or open an existing one.
Open _Window -> Package Manager_, click on the plus sign, _Add Package by name..._ and insert `com.unity.webrtc`. Wait for the package to be installed.
In the _Project_ window, under `Assets`, create a new C# Script called `WebRTCPublisher.cs` with this content:
```cs
using System.Collections;
using UnityEngine;
using Unity.WebRTC;
using UnityEngine.Networking;
public class WebRTCPublisher : MonoBehaviour
{
public string url = "http://localhost:8889/unity/whip";
public int videoWidth = 1280;
public int videoHeight = 720;
private RTCPeerConnection pc;
private MediaStream videoStream;
void Start()
{
pc = new RTCPeerConnection();
Camera sourceCamera = gameObject.GetComponent<Camera>();
videoStream = sourceCamera.CaptureStream(videoWidth, videoHeight);
foreach (var track in videoStream.GetTracks())
{
pc.AddTrack(track);
}
StartCoroutine(WebRTC.Update());
StartCoroutine(createOffer());
}
private IEnumerator createOffer()
{
var op = pc.CreateOffer();
yield return op;
if (op.IsError) {
Debug.LogError("CreateOffer() failed");
yield break;
}
yield return setLocalDescription(op.Desc);
}
private IEnumerator setLocalDescription(RTCSessionDescription offer)
{
var op = pc.SetLocalDescription(ref offer);
yield return op;
if (op.IsError) {
Debug.LogError("SetLocalDescription() failed");
yield break;
}
yield return postOffer(offer);
}
private IEnumerator postOffer(RTCSessionDescription offer)
{
var content = new System.Net.Http.StringContent(offer.sdp);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/sdp");
var client = new System.Net.Http.HttpClient();
var task = System.Threading.Tasks.Task.Run(async () => {
var res = await client.PostAsync(new System.UriBuilder(url).Uri, content);
res.EnsureSuccessStatusCode();
return await res.Content.ReadAsStringAsync();
});
yield return new WaitUntil(() => task.IsCompleted);
if (task.Exception != null) {
Debug.LogError(task.Exception);
yield break;
}
yield return setRemoteDescription(task.Result);
}
private IEnumerator setRemoteDescription(string answer)
{
RTCSessionDescription desc = new RTCSessionDescription();
desc.type = RTCSdpType.Answer;
desc.sdp = answer;
var op = pc.SetRemoteDescription(ref desc);
yield return op;
if (op.IsError) {
Debug.LogError("SetRemoteDescription() failed");
yield break;
}
yield break;
}
void OnDestroy()
{
pc?.Close();
pc?.Dispose();
videoStream?.Dispose();
}
}
```
In the _Hierarchy_ window, find or create a scene and a camera, then add the `WebRTCPublisher.cs` script as component of the camera, by dragging it inside the _Inspector_ window. then Press the _Play_ button at the top of the page.
The resulting stream will be available on path `/unity`.
================================================
FILE: docs/2-publish/21-web-browsers.md
================================================
# Web browsers
Web browsers can publish a stream to the server by using the [WebRTC protocol](04-webrtc-clients.md). Start the server and open the web page:
```
http://localhost:8889/mystream/publish
```
The resulting stream will be available on path `/mystream`.
This web page can be embedded into another web page by using an iframe:
```html
<iframe src="http://mediamtx-ip:8889/mystream/publish" scrolling="no"></iframe>
```
For more advanced setups, you can create and serve a custom web page by starting from the [source code of the WebRTC publish page](https://github.com/bluenviron/mediamtx/blob/{version_tag}/internal/servers/webrtc/publish_index.html). In particular, there's a ready-to-use, standalone JavaScript class for publishing streams with WebRTC, available in [publisher.js](https://github.com/bluenviron/mediamtx/blob/{version_tag}/internal/servers/webrtc/publisher.js).
================================================
FILE: docs/2-publish/index.md
================================================
# Publish
================================================
FILE: docs/3-read/01-overview.md
================================================
# Read a stream
Live streams can be read from the server with the following protocols and codecs:
| protocol | variants | codecs |
| ------------------------------ | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [SRT clients](02-srt.md) | | **Video**: H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3<br/>**Other**: KLV |
| [WebRTC clients](03-webrtc.md) | WHEP | **Video**: AV1, VP9, VP8, H265, H264<br/>**Audio**: Opus, G722, G711 (PCMA, PCMU)<br/>**Other**: KLV |
| [RTSP clients](04-rtsp.md) | UDP, UDP-Multicast, TCP, RTSPS | **Video**: AV1, VP9, VP8, H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video, M-JPEG<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3, G726, G722, G711 (PCMA, PCMU), LPCM<br/>**Other**: KLV, MPEG-TS, any RTP-compatible codec |
| [RTMP clients](05-rtmp.md) | RTMP, RTMPS, Enhanced RTMP | **Video**: AV1, VP9, H265, H264<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3, G711 (PCMA, PCMU), LPCM |
| [HLS](06-hls.md) | Low-Latency HLS, MP4-based HLS, legacy HLS | **Video**: AV1, VP9, H265, H264<br/>**Audio**: Opus, MPEG-4 Audio (AAC) |
We provide instructions for reading with the following software:
- [FFmpeg](07-ffmpeg.md)
- [GStreamer](08-gstreamer.md)
- [VLC](09-vlc.md)
- [OBS Studio](10-obs-studio.md)
- [Python and OpenCV](11-python-opencv.md)
- [Golang](12-golang.md)
- [Unity](13-unity.md)
- [Web browsers](14-web-browsers.md)
================================================
FILE: docs/3-read/02-srt.md
================================================
# SRT clients
SRT is a protocol that allows to publish and read live data stream, providing encryption, integrity and a retransmission mechanism. It is usually used to transfer media streams encoded with MPEG-TS. In order to read a stream from the server with the SRT protocol, use this URL:
```
srt://localhost:8890?streamid=read:mystream
```
Replace `mystream` with the path name.
If you need to use the standard stream ID syntax instead of the custom one in use by this server, read [Standard stream ID syntax](../4-other/21-srt-specific-features.md#standard-stream-id-syntax).
Some clients that can read with SRT are [FFmpeg](07-ffmpeg.md), [GStreamer](08-gstreamer.md) and [VLC](09-vlc.md).
================================================
FILE: docs/3-read/03-webrtc.md
================================================
# WebRTC clients
WebRTC is an API that makes use of a set of protocols and methods to connect two clients together and allow them to exchange live media or data streams. You can read a stream with WebRTC and a web browser by visiting:
```
http://localhost:8889/mystream
```
WHEP is a WebRTC extension that allows to read streams by using a URL, without passing through a web page. This allows to use WebRTC as a general purpose streaming protocol. If you are using a software that supports WHEP, you can read a stream from the server by using this URL:
```
http://localhost:8889/mystream/whep
```
Be aware that not all browsers can read any codec, check [Supported browsers](../4-other/22-webrtc-specific-features.md#supported-browsers).
Depending on the network it may be difficult to establish a connection between server and clients, read [Solving WebRTC connectivity issues](../4-other/22-webrtc-specific-features.md#solving-webrtc-connectivity-issues).
Some clients that can read with WebRTC and WHEP are [FFmpeg](07-ffmpeg.md), [GStreamer](08-gstreamer.md), [Unity](13-unity.md) and [web browsers](14-web-browsers.md).
================================================
FILE: docs/3-read/04-rtsp.md
================================================
# RTSP clients
RTSP is a protocol that allows to publish and read streams. It supports several underlying transport protocols and encryption (read [RTSP-specific features](../4-other/23-rtsp-specific-features.md)). In order to read a stream with the RTSP protocol, use this URL:
```
rtsp://localhost:8554/mystream
```
Some clients that can read with RTSP are [FFmpeg](07-ffmpeg.md), [GStreamer](08-gstreamer.md) and [VLC](09-vlc.md).
================================================
FILE: docs/3-read/05-rtmp.md
================================================
# RTMP clients
RTMP is a protocol that allows to read and publish streams. It supports encryption, read [RTMP-specific features](../4-other/24-rtmp-specific-features.md). Streams can be read from the server by using the URL:
```
rtmp://localhost/mystream
```
Some clients that can read with RTMP are [FFmpeg](07-ffmpeg.md), [GStreamer](08-gstreamer.md) and [VLC](09-vlc.md).
================================================
FILE: docs/3-read/06-hls.md
================================================
# HLS
HLS is a protocol that works by splitting streams into segments, and by serving these segments and a playlist with the HTTP protocol. You can use _MediaMTX_ to generate an HLS stream, that is accessible through a web page:
```
http://localhost:8888/mystream
```
and can also be accessed without using the browsers, by software that supports the HLS protocol (for instance VLC or _MediaMTX_ itself) by using this URL:
```
http://localhost:8888/mystream/index.m3u8
```
Some clients that can read with HLS are [FFmpeg](07-ffmpeg.md), [GStreamer](08-gstreamer.md), [VLC](09-vlc.md) and [web browsers](14-web-browsers.md).
================================================
FILE: docs/3-read/07-ffmpeg.md
================================================
# FFmpeg
FFmpeg can read a stream from the server in several ways. The recommended one consists in reading with RTSP.
## FFmpeg and RTSP
```sh
ffmpeg -i rtsp://localhost:8554/mystream -c copy output.mp4
```
## FFmpeg and RTMP
```sh
ffmpeg -i rtmp://localhost/mystream -c copy output.mp4
```
In order to read AV1, VP9, H265, Opus, AC3 tracks and in order to read multiple video or audio tracks, the `-rtmp_enhanced_codecs` flag must be present:
```sh
ffmpeg -rtmp_enhanced_codecs ac-3,av01,avc1,ec-3,fLaC,hvc1,.mp3,mp4a,Opus,vp09 \
-i rtmp://localhost/mystream -c copy output.mp4
```
## FFmpeg and SRT
```sh
ffmpeg -i 'srt://localhost:8890?streamid=read:test' -c copy output.mp4
```
================================================
FILE: docs/3-read/08-gstreamer.md
================================================
# GStreamer
GStreamer can read a stream from the server in several ways. The recommended one consists in reading with RTSP.
## GStreamer and RTSP
```sh
gst-launch-1.0 rtspsrc location=rtsp://127.0.0.1:8554/mystream latency=0 ! decodebin ! autovideosink
```
For advanced options, read [RTSP-specific features](../4-other/23-rtsp-specific-features.md).
## GStreamer and WebRTC
GStreamer also supports reading streams with WebRTC/WHEP, although track codecs must be specified in advance through the `video-caps` and `audio-caps` parameters. Furthermore, if audio is not present, `audio-caps` must be set anyway and must point to a PCMU codec. For instance, the command for reading a video-only H264 stream is:
```sh
gst-launch-1.0 whepsrc whep-endpoint=http://127.0.0.1:8889/stream/whep use-link-headers=true \
video-caps="application/x-rtp,media=video,encoding-name=H264,payload=127,clock-rate=90000" \
audio-caps="application/x-rtp,media=audio,encoding-name=PCMU,payload=0,clock-rate=8000" \
! rtph264depay ! decodebin ! autovideosink
```
While the command for reading an audio-only Opus stream is:
```sh
gst-launch-1.0 whepsrc whep-endpoint="http://127.0.0.1:8889/stream/whep" use-link-headers=true \
audio-caps="application/x-rtp,media=audio,encoding-name=OPUS,payload=111,clock-rate=48000,encoding-params=(string)2" \
! rtpopusdepay ! decodebin ! autoaudiosink
```
While the command for reading a H264 and Opus stream is:
```sh
gst-launch-1.0 whepsrc whep-endpoint=http://127.0.0.1:8889/stream/whep use-link-headers=true \
video-caps="application/x-rtp,media=video,encoding-name=H264,payload=127,clock-rate=90000" \
audio-caps="application/x-rtp,media=audio,encoding-name=OPUS,payload=111,clock-rate=48000,encoding-params=(string)2" \
! decodebin ! autovideosink
```
================================================
FILE: docs/3-read/09-vlc.md
================================================
# VLC
VLC can read a stream from the server in several ways. The recommended one consists in reading with RTSP:
```sh
vlc --network-caching=50 rtsp://localhost:8554/mystream
```
## RTSP and Ubuntu compatibility
The VLC shipped with Ubuntu 21.10 doesn't support playing RTSP due to a license issue (read [here](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=982299) and [here](https://stackoverflow.com/questions/69766748/cvlc-cannot-play-rtsp-omxplayer-instead-can)). To fix the issue, remove the default VLC instance and install the snap version:
```sh
sudo apt purge -y vlc
snap install vlc
```
## Encrypted RTSP compatibility
At the moment VLC doesn't support reading encrypted RTSP streams. However, you can use a proxy like [stunnel](https://www.stunnel.org) or [nginx](https://nginx.org/) or a local _MediaMTX_ instance to decrypt streams before reading them.
================================================
FILE: docs/3-read/10-obs-studio.md
================================================
# OBS Studio
OBS Studio can read streams from the server by using the [RTSP protocol](04-rtsp.md).
Open OBS, click on _Add Source_, _Media source_, _OK_, uncheck _Local file_, insert in _Input_:
```
rtsp://localhost:8554/stream
```
Then _Ok_.
================================================
FILE: docs/3-read/11-python-opencv.md
================================================
# Python and OpenCV
Python-based software can read streams from the server with the OpenCV library, acting as a [RTSP client](04-rtsp.md).
```python
import cv2
cap = cv2.VideoCapture('rtsp://localhost:8554/mystream')
if not cap.isOpened():
raise Exception("can't open video capture")
while True:
ret, frame = cap.read()
if not ret:
raise Exception("can't receive frame")
cv2.imshow('frame', frame)
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
```
================================================
FILE: docs/3-read/12-golang.md
================================================
# Golang
You can read a stream from the server by using the Go programming language and the following libraries:
- [gortsplib](https://github.com/bluenviron/gortsplib) to read with RTSP.
- [gortmplib](https://github.com/bluenviron/gortmplib) to read with RTMP.
- [gohlslib](https://github.com/bluenviron/gohlslib) to read with HLS.
All these power _MediaMTX_ itself. In the repositories of these projects there are several examples on how to connect to a server and read data.
================================================
FILE: docs/3-read/13-unity.md
================================================
# Unity
Software written with the Unity Engine can read a stream from the server by using the [WebRTC protocol](03-webrtc.md).
Create a new Unity project or open an existing one.
Open _Window -> Package Manager_, click on the plus sign, _Add Package by name..._ and insert `com.unity.webrtc`. Wait for the package to be installed.
In the _Project_ window, under `Assets`, create a new C# Script called `WebRTCReader.cs` with this content:
```cs
using System.Collections;
using UnityEngine;
using Unity.WebRTC;
public class WebRTCReader : MonoBehaviour
{
public string url = "http://localhost:8889/stream/whep";
private RTCPeerConnection pc;
private MediaStream receiveStream;
void Start()
{
UnityEngine.UI.RawImage rawImage = gameObject.GetComponentInChildren<UnityEngine.UI.RawImage>();
AudioSource audioSource = gameObject.GetComponentInChildren<AudioSource>();
pc = new RTCPeerConnection();
receiveStream = new MediaStream();
pc.OnTrack = e =>
{
receiveStream.AddTrack(e.Track);
};
receiveStream.OnAddTrack = e =>
{
if (e.Track is VideoStreamTrack videoTrack)
{
videoTrack.OnVideoReceived += (tex) =>
{
rawImage.texture = tex;
};
}
else if (e.Track is AudioStreamTrack audioTrack)
{
audioSource.SetTrack(audioTrack);
audioSource.loop = true;
audioSource.Play();
}
};
RTCRtpTransceiverInit init = new RTCRtpTransceiverInit();
init.direction = RTCRtpTransceiverDirection.RecvOnly;
pc.AddTransceiver(TrackKind.Audio, init);
pc.AddTransceiver(TrackKind.Video, init);
StartCoroutine(WebRTC.Update());
StartCoroutine(createOffer());
}
private IEnumerator createOffer()
{
var op = pc.CreateOffer();
yield return op;
if (op.IsError) {
Debug.LogError("CreateOffer() failed");
yield break;
}
yield return setLocalDescription(op.Desc);
}
private IEnumerator setLocalDescription(RTCSessionDescription offer)
{
var op = pc.SetLocalDescription(ref offer);
yield return op;
if (op.IsError) {
Debug.LogError("SetLocalDescription() failed");
yield break;
}
yield return postOffer(offer);
}
private IEnumerator postOffer(RTCSessionDescription offer)
{
var content = new System.Net.Http.StringContent(offer.sdp);
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/sdp");
var client = new System.Net.Http.HttpClient();
var task = System.Threading.Tasks.Task.Run(async () => {
var res = await client.PostAsync(new System.UriBuilder(url).Uri, content);
res.EnsureSuccessStatusCode();
return await res.Content.ReadAsStringAsync();
});
yield return new WaitUntil(() => task.IsCompleted);
if (task.Exception != null) {
Debug.LogError(task.Exception);
yield break;
}
yield return setRemoteDescription(task.Result);
}
private IEnumerator setRemoteDescription(string answer)
{
RTCSessionDescription desc = new RTCSessionDescription();
desc.type = RTCSdpType.Answer;
desc.sdp = answer;
var op = pc.SetRemoteDescription(ref desc);
yield return op;
if (op.IsError) {
Debug.LogError("SetRemoteDescription() failed");
yield break;
}
yield break;
}
void OnDestroy()
{
pc?.Close();
pc?.Dispose();
receiveStream?.Dispose();
}
}
```
Edit the `url` variable according to your needs.
In the _Hierarchy_ window, find or create a scene. Inside the scene, add a _Canvas_. Inside the Canvas, add a _Raw Image_ and an _Audio Source_. Then add the `WebRTCReader.cs` script as component of the canvas, by dragging it inside the _Inspector_ window. then Press the _Play_ button at the top of the page.
================================================
FILE: docs/3-read/14-web-browsers.md
================================================
# Web browsers
Web browsers can read a stream from the server in several ways.
## Web browsers and WebRTC
You can read a stream by using the [WebRTC protocol](03-webrtc.md) by visiting the web page:
```
http://localhost:8889/mystream
```
See [Embed streams in a website](../4-other/14-embed-streams-in-a-website.md) for instructions on how to embed the stream into an external website.
## Web browsers and HLS
Web browsers can also read a stream with the [HLS protocol](06-hls.md). Latency is higher but there are fewer problems related to connectivity between server and clients, furthermore the server load can be balanced by using a common HTTP CDN (like Cloudflare or CloudFront), and this allows to handle an unlimited amount of readers. Visit the web page:
```
http://localhost:8888/mystream
```
See [Embed streams in a website](../4-other/14-embed-streams-in-a-website.md) for instructions on how to embed the stream into an external website.
================================================
FILE: docs/3-read/index.md
================================================
# Read
================================================
FILE: docs/4-other/02-configuration.md
================================================
# Configuration
All the configuration parameters are listed and commented in the [configuration file](../5-references/1-configuration-file.md) (`mediamtx.yml`).
## Change the configuration
There are several ways to change the configuration:
1. By editing the configuration file, that is
- included into the release bundle
- available in the root folder of the Docker image (`/mediamtx.yml`); it can be overridden in this way:
```sh
docker run --rm -it --network=host -v "$PWD/mediamtx.yml:/mediamtx.yml:ro" bluenviron/mediamtx:1
```
The configuration can be changed dynamically when the server is running (hot reloading) by writing to the configuration file. Changes are detected and applied without disconnecting existing clients, whenever it's possible.
2. By overriding configuration parameters with environment variables, in the format `MTX_PARAMNAME`, where `PARAMNAME` is the uppercase name of a parameter. For instance, the `rtspAddress` parameter can be overridden in the following way:
```
MTX_RTSPADDRESS="127.0.0.1:8554" ./mediamtx
```
Parameters that have array as value can be overridden by setting a comma-separated list. For example:
```
MTX_RTSPTRANSPORTS="tcp,udp"
```
Parameters in maps can be overridden by using underscores, in the following way:
```
MTX_PATHS_TEST_SOURCE=rtsp://myurl ./mediamtx
```
Parameters in lists can be overridden in the same way as parameters in maps, using their position like an additional key. This is particularly useful if you want to use internal users but define credentials through environment variables:
```
MTX_AUTHINTERNALUSERS_0_USER=username
MTX_AUTHINTERNALUSERS_0_PASS=password
```
This method is particularly useful when using Docker; any configuration parameter can be changed by passing environment variables with the `-e` flag:
```
docker run --rm -it --network=host -e MTX_PATHS_TEST_SOURCE=rtsp://myurl bluenviron/mediamtx:1
```
3. By using the [Control API](18-control-api.md).
## Encrypt the configuration
The configuration file can be entirely encrypted for security purposes by using the `crypto_secretbox` function of the NaCL function. An online tool for performing this operation is [available here](https://play.golang.org/p/rX29jwObNe4).
After performing the encryption, put the base64-encoded result into the configuration file, and launch the server with the `MTX_CONFKEY` variable:
```
MTX_CONFKEY=mykey ./mediamtx
```
================================================
FILE: docs/4-other/03-authentication.md
================================================
# Authentication
_MediaMTX_ can be configured to ask clients for credentials, either in the form of username/password or a string-based token. These credentials are then validated through a chosen method.
## Credential validation
Credentials can be validated through one of these methods:
- Internal database: credentials are stored in the configuration file
- External HTTP server: an external HTTP URL is contacted to perform authentication
- External JWT provider: an external identity server provides signed tokens that are then verified by the server
### Internal database
The internal authentication method is the default one. Users are stored inside the configuration file, in this format:
```yml
authInternalUsers:
# Username. 'any' means any user, including anonymous ones.
- user: any
# Password. Not used in case of 'any' user.
pass:
# IPs or networks allowed to use this user. An empty list means any IP.
ips: []
# Permissions.
permissions:
# Available actions are: publish, read, playback, api, metrics, pprof.
- action: publish
# Paths can be set to further restrict access to a specific path.
# An empty path means any path.
# Regular expressions can be used by using a tilde as prefix.
path:
- action: read
path:
- action: playback
path:
```
Only clients that provide a valid username and password will be able to perform a certain action.
If storing plain credentials in the configuration file is a security problem, username and passwords can be stored as hashed strings. The Argon2 and SHA256 hashing algorithms are supported. To use Argon2, the string must be hashed using Argon2id (recommended) or Argon2i:
```
echo -n "mypass" | argon2 saltItWithSalt -id -l 32 -e
```
Then stored with the `argon2:` prefix:
```yml
authInternalUsers:
- user: argon2:$argon2id$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$OGGO0eCMN0ievb4YGSzvS/H+Vajx1pcbUmtLp2tRqRU
pass: argon2:$argon2i$v=19$m=4096,t=3,p=1$MTIzNDU2Nzg$oct3kOiFywTdDdt19kT07hdvmsPTvt9zxAUho2DLqZw
permissions:
- action: publish
```
To use SHA256, the string must be hashed with SHA256 and encoded with base64:
```
echo -n "mypass" | openssl dgst -binary -sha256 | openssl base64
```
Then stored with the `sha256:` prefix:
```yml
authInternalUsers:
- user: sha256:j1tsRqDEw9xvq/D7/9tMx6Jh/jMhk3UfjwIB2f1zgMo=
pass: sha256:BdSWkrdV+ZxFBLUQQY7+7uv9RmiSVA8nrPmjGjJtZQQ=
permissions:
- action: publish
```
**WARNING**: enable encryption or use a VPN to ensure that no one is intercepting the credentials in transit.
### External HTTP server
Authentication can be delegated to an external HTTP server:
```yml
authMethod: http
authHTTPAddress: http://myauthserver/auth
```
Each time a user needs to be authenticated, the specified URL will be requested with the POST method and this payload:
```json
{
"user": "user",
"password": "password",
"token": "token",
"ip": "ip",
"action": "publish|read|playback|api|metrics|pprof",
"path": "path",
"protocol": "rtsp|rtmp|hls|webrtc|srt",
"id": "id",
"query": "query"
}
```
If the URL returns a status code that begins with `20` (i.e. `200`), authentication is successful, otherwise it fails. Be aware that it's perfectly normal for the authentication server to receive requests with empty users and passwords, i.e.:
```json
{
"user": "",
"password": ""
}
```
This happens because RTSP clients don't provide credentials until they are asked to. In order to receive the credentials, the authentication server must reply with status code `401`, then the client will send credentials.
Some actions can be excluded from the process:
```yml
# Actions to exclude from HTTP-based authentication.
# Format is the same as the one of user permissions.
authHTTPExclude:
- action: api
- action: metrics
- action: pprof
```
If the authentication server uses HTTPS and has a self-signed or invalid TLS certificate, you can provide the fingerprint of the certificate to validate it anyway:
```yml
authMethod: http
authHTTPAddress: https://myauthserver/auth
authHTTPFingerprint: 33949e05fffb5ff3e8aa16f8213a6251b4d9363804ba53233c4da9a46d6f2739
```
The fingerprint can be obtained with:
```sh
openssl s_client -connect myauthserver:443 </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
```
### External JWT provider
Authentication can be delegated to an external identity server, that is capable of generating JWTs and provides a JWKS endpoint. With respect to the HTTP-based method, this has the advantage that the external server is contacted once, and not for every request, greatly improving performance. In order to use the JWT-based authentication method, set `authMethod` and `authJWTJWKS`:
```yml
authMethod: jwt
authJWTJWKS: http://my_identity_server/jwks_endpoint
authJWTClaimKey: mediamtx_permissions
```
Users are expected to pass the encoded JWT as token.
The JWT is expected to contain a claim, with a list of permissions in the same format as the one of user permissions:
```json
{
"mediamtx_permissions": [
{
"action": "publish",
"path": ""
}
]
}
```
If the JWKS server uses TLS and has a self-signed or invalid TLS certificate, you can provide the fingerprint of the certificate to validate it anyway:
```yml
authMethod: jwt
authJWTJWKS: https://my_identity_server/jwks_endpoint
authJWTJWKSFingerprint: 33949e05fffb5ff3e8aa16f8213a6251b4d9363804ba53233c4da9a46d6f2739
authJWTClaimKey: mediamtx_permissions
```
The fingerprint can be obtained with:
```sh
openssl s_client -connect my_identity_server:443 </dev/null 2>/dev/null | sed -n '/BEGIN/,/END/p' > server.crt
openssl x509 -in server.crt -noout -fingerprint -sha256 | cut -d "=" -f2 | tr -d ':'
```
Optionally, the JWT `iss` (issuer) and `aud` (audience) claims can be validated by setting `authJWTIssuer` and `authJWTAudience`. When set, tokens that don't contain the expected values will be rejected:
```yml
authMethod: jwt
authJWTJWKS: http://my_identity_server/jwks_endpoint
authJWTClaimKey: mediamtx_permissions
authJWTIssuer: http://my_identity_server
authJWTAudience: mediamtx
```
Leave these fields empty to skip validation of the respective claims.
#### Keycloak setup
Here's a tutorial on how to setup the [Keycloak identity server](https://www.keycloak.org/) in order to provide JWTs.
1. Start Keycloak:
```sh
docker run --name=keycloak -p 8080:8080 \
-e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:23.0.7 start-dev
```
2. Open the Keycloak web UI on http://localhost:8080, click on _Administration Console_ and log in.
3. Click on _master_ in the top left corner, _Create realm_, set realm name to `mediamtx`, _Create_.
4. Open page _Client scopes_, _Create client scope_, set name to `mediamtx`, _Save_.
5. Open tab _Mappers_, _Configure a new Mapper_, _User Attribute_:
- Name: `mediamtx_permissions`
- User Attribute: `mediamtx_permissions`
- Token Claim Name: `mediamtx_permissions`
- Claim JSON Type: `JSON`
- Multivalued: `On`
Save.
6. Open page _Clients_, _Create client_, set Client ID to `mediamtx`, _Next_, _Client authentication_ `On`, _Next_, _Save_.
7. Open tab _Credentials_, copy client secret somewhere.
8. Open tab _Client scopes_, set _Assigned type_ of all existing client scopes to _Optional_. This decreases the length of the JWT, since many clients impose limits on it.
9. In tab _Client scopes_, _Add client scope_, Select `mediamtx`, _Add_, _Default_.
10. Open page _Users_, _Add user_, Username `testuser`, _Create_, Tab _Credentials_, _Set password_, pick a password, _Save_.
11. Open tab _Attributes_, _Add an attribute_:
- Key: `mediamtx_permissions`
- Value: `{"action":"publish", "path": ""}`
You can add as many attributes with key `mediamtx_permissions` as you want, each with a single permission in it.
12. In MediaMTX, use the following JWKS URL:
```yml
authJWTJWKS: http://localhost:8080/realms/mediamtx/protocol/openid-connect/certs
```
13. Perform authentication on Keycloak:
```
curl \
-d "client_id=mediamtx" \
-d "client_secret=$CLIENT_SECRET" \
-d "username=$USER" \
-d "password=$PASS" \
-d "grant_type=password" \
http://localhost:8080/realms/mediamtx/protocol/openid-connect/token
```
The JWT is inside the `access_token` key of the response:
```json
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIyNzVjX3ptOVlOdHQ0TkhwWVk4Und6ZndUclVGSzRBRmQwY3lsM2wtY3pzIn0.eyJleHAiOjE3MDk1NTUwOTIsImlhdCI6MTcwOTU1NDc5MiwianRpIjoiMzE3ZTQ1NGUtNzczMi00OTM1LWExNzAtOTNhYzQ2ODhhYWIxIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9tZWRpYW10eCIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiI2NTBhZDA5Zi03MDgxLTQyNGItODI4Ni0xM2I3YTA3ZDI0MWEiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJtZWRpYW10eCIsInNlc3Npb25fc3RhdGUiOiJjYzJkNDhjYy1kMmU5LTQ0YjAtODkzZS0wYTdhNjJiZDI1YmQiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIi8qIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIiwiZGVmYXVsdC1yb2xlcy1tZWRpYW10eCJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoibWVkaWFtdHggcHJvZmlsZSBlbWFpbCIsInNpZCI6ImNjMmQ0OGNjLWQyZTktNDRiMC04OTNlLTBhN2E2MmJkMjViZCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibWVkaWFtdHhfcGVybWlzc2lvbnMiOlt7ImFjdGlvbiI6InB1Ymxpc2giLCJwYXRocyI6ImFsbCJ9XSwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdHVzZXIifQ.Gevz7rf1qHqFg7cqtSfSP31v_NS0VH7MYfwAdra1t6Yt5rTr9vJzqUeGfjYLQWR3fr4XC58DrPOhNnILCpo7jWRdimCnbPmuuCJ0AYM-Aoi3PAsWZNxgmtopq24_JokbFArY9Y1wSGFvF8puU64lt1jyOOyxf2M4cBHCs_EarCKOwuQmEZxSf8Z-QV9nlfkoTUszDCQTiKyeIkLRHL2Iy7Fw7_T3UI7sxJjVIt0c6HCNJhBBazGsYzmcSQ_GrmhbUteMTg00o6FicqkMBe99uZFnx9wIBm_QbO9hbAkkzF923I-DTAQrFLxT08ESMepDwmzFrmnwWYBLE3u8zuUlCA",
"expires_in": 300,
"refresh_expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI3OTI3Zjg4Zi05YWM4LTRlNmEtYWE1OC1kZmY0MDQzZDRhNGUifQ.eyJleHAiOjE3MDk1NTY1OTIsImlhdCI6MTcwOTU1NDc5MiwianRpIjoiMGVhZWFhMWItYzNhMC00M2YxLWJkZjAtZjI2NTRiODlkOTE3IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9tZWRpYW10eCIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9yZWFsbXMvbWVkaWFtdHgiLCJzdWIiOiI2NTBhZDA5Zi03MDgxLTQyNGItODI4Ni0xM2I3YTA3ZDI0MWEiLCJ0eXAiOiJSZWZyZXNoIiwiYXpwIjoibWVkaWFtdHgiLCJzZXNzaW9uX3N0YXRlIjoiY2MyZDQ4Y2MtZDJlOS00NGIwLTg5M2UtMGE3YTYyYmQyNWJkIiwic2NvcGUiOiJtZWRpYW10eCBwcm9maWxlIGVtYWlsIiwic2lkIjoiY2MyZDQ4Y2MtZDJlOS00NGIwLTg5M2UtMGE3YTYyYmQyNWJkIn0.yuXV8_JU0TQLuosNdp5xlYMjn7eO5Xq-PusdHzE7bsQ",
"token_type": "Bearer",
"not-before-policy": 0,
"session_state": "cc2d48cc-d2e9-44b0-893e-0a7a62bd25bd",
"scope": "mediamtx profile email"
}
```
## Providing username and password
### RTSP
Prepend username and password and a `@` to the host:
```
rtsp rtsp://myuser:mypass@localhost:8554/mystream
```
### RTMP
Use the `user` and `pass` query parameters:
```
rtmp://localhost/mystream?user=myuser&pass=mypass
```
### SRT
Append username and password to `streamid`:
```
srt://localhost:8890?streamid=publish:mystream:user:pass&pkt_size=1316
```
### HLS and WebRTC
Username and password can be passed through the `Authorization: Basic` HTTP header:
```
Authorization: Basic base64(user:pass)
```
When using a web browser, a dialog is first shown to users, asking for credentials, and then the header is automatically inserted into every request. If you need to automatically fill credentials from a parent web page, read [Embed streams in a website](14-embed-streams-in-a-website.md).
If the `Authorization: Basic` header cannot be used (for instance, in software like OBS Studio, which only allows to provide a "Bearer Token"), credentials can be passed through the `Authorization: Bearer` header (i.e. the "Bearer Token" in OBS), where the value is the concatenation of username and password, separated by a colon:
```
Authorization: Bearer username:password
```
## Providing tokens / JWTs
### RTSP
Pass the token as a query parameter:
```
rtsp://localhost:8554/mystream?jwt=jwt
```
WARNING: FFmpeg implementation of RTSP does not support URLs that are longer than 4096 characters (this is the [MAX_URL_SIZE constant](https://github.com/FFmpeg/FFmpeg/blob/f951aa9ef382d6bb517e05d04d52710f751de427/libavformat/internal.h#L30)), therefore you have to configure your identity server in order to produce JWTs that are shorter than this threshold.
### RTMP
Pass the token as a query parameter:
```
rtmp://localhost/mystream?jwt=jwt
```
WARNING: FFmpeg implementation of RTMP does not support URLs that are longer than 1024 characters (this is the [TCURL_MAX_LENGTH constant](https://github.com/FFmpeg/FFmpeg/blob/f951aa9ef382d6bb517e05d04d52710f751de427/libavformat/rtmpproto.c#L55)), therefore you have to configure your identity server in order to produce JWTs that are shorter than this threshold.
### SRT
Pass the token as password, with an arbitrary user:
```
srt://localhost:8890?streamid=publish:mystream:user:jwt&pkt_size=1316
```
WARNING: SRT does not support Stream IDs that are longer than 512 characters, therefore you have to configure your identity server in order to produce JWTs that are shorter than this threshold.
### HLS and WebRTC
The token can be passed through the `Authorization: Bearer` header:
```
Authorization: Bearer MY_JWT
```
In OBS Studio, this is the "Bearer Token" field.
If the `Authorization: Bearer` token cannot be directly provided (for instance, with web browsers that directly access _MediaMTX_ and show a credential dialog), you can pass the token as password, using an arbitrary user.
In web browsers, if you need to automatically fill credentials from a parent web page, read [Embed streams in a website](14-embed-streams-in-a-website.md).
================================================
FILE: docs/4-other/04-remuxing-reencoding-compression.md
================================================
# Re-encoding
To change the format, codec or compression of a stream, use _FFmpeg_ or _GStreamer_ together with _MediaMTX_. For instance, to re-encode an existing stream, that is available in the `/original` path, and publish the resulting stream in the `/compressed` path, edit `mediamtx.yml` and replace everything inside section `paths` with the following content:
```yml
paths:
compressed:
original:
runOnReady: >
ffmpeg -i rtsp://localhost:$RTSP_PORT/$MTX_PATH
-c:v libx264 -pix_fmt yuv420p -preset ultrafast -b:v 600k
-max_muxing_queue_size 1024 -f rtsp rtsp://localhost:$RTSP_PORT/compressed
runOnReadyRestart: yes
```
================================================
FILE: docs/4-other/05-always-available.md
================================================
# Always-available
When the publisher or source of a stream is offline, the server can be configured to fill gaps in the stream with an offline segment that is played on repeat until a publisher comes back online. This allows readers to stay connected regardless of the state of the stream. The offline segment and online stream are concatenated without re-encoding any frame, using the original codec.
This feature can be enabled by toggling the `alwaysAvailable` flag and filling `alwaysAvailableTracks`:
```yml
paths:
mypath:
alwaysAvailable: true
alwaysAvailableTracks:
# Available values are: AV1, VP9, H265, H264, Opus, MPEG4Audio, G711, LPCM
- codec: H264
# in case of MPEG4Audio, G711, LPCM, sampleRate and ChannelCount must be provided too.
# sampleRate: 48000
# channelCount: 2
# in case of G711, muLaw must be provided too.
# muLaw: false
```
By default, the server uses a default offline segment with the text "STREAM IS OFFLINE". The segment can be replaced with an external MP4 file:
```yml
paths:
mypath:
alwaysAvailable: true
alwaysAvailableFile: "./h264.mp4"
```
================================================
FILE: docs/4-other/06-record.md
================================================
# Record
Live streams be recorded to disk and played back with the following file containers and codecs:
| container | codecs |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| fMP4 | **Video**: AV1, VP9, H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video, M-JPEG<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3, G711 (PCMA, PCMU), LPCM |
| MPEG-TS | **Video**: H265, H264, MPEG-4 Video (H263, Xvid), MPEG-1/2 Video<br/>**Audio**: Opus, MPEG-4 Audio (AAC), MPEG-1/2 Audio (MP3), AC-3 |
## Usage
To record available streams to disk, set the `record` parameter in the configuration file:
```yml
pathDefaults:
# Record streams to disk.
record: yes
```
It's also possible to specify additional parameters:
```yml
pathDefaults:
# Record streams to disk.
record: yes
# Path of recording segments.
# Extension is added automatically.
# Available variables are %path (path name), %Y %m %d (year, month, day),
# %H %M %S (hours, minutes, seconds), %f (microseconds), %z (time zone), %s (unix epoch).
recordPath: ./recordings/%path/%Y-%m-%d_%H-%M-%S-%f
# Format of recorded segments.
# Available formats are "fmp4" (fragmented MP4) and "mpegts" (MPEG-TS).
recordFormat: fmp4
# fMP4 segments are concatenation of small MP4 files (parts), each with this duration.
# MPEG-TS segments are concatenation of 188-bytes packets, flushed to disk with this period.
# When a system failure occurs, the last part gets lost.
# Therefore, the part duration is equal to the RPO (recovery point objective).
recordPartDuration: 1s
# This prevents RAM exhaustion.
recordMaxPartSize: 50M
# Minimum duration of each segment.
recordSegmentDuration: 1h
# Delete segments after this timespan.
# Set to 0s to disable automatic deletion.
recordDeleteAfter: 1d
```
All available recording parameters are listed in the [configuration file](../5-references/1-configuration-file.md).
## Remote upload
To upload recordings to a remote location, you can use _MediaMTX_ together with [rclone](https://github.com/rclone/rclone), a command line tool that provides file synchronization capabilities with a huge variety of services (including S3, FTP, SMB, Google Drive):
1. Download and install [rclone](https://github.com/rclone/rclone).
2. Configure _rclone_:
```sh
rclone config
```
3. Place `rclone` into the `runOnInit` and `runOnRecordSegmentComplete` hooks:
```yml
pathDefaults:
# this is needed to sync segments after a crash.
# replace myconfig with the name of the rclone config.
runOnInit: rclone sync -v ./recordings myconfig:/my-path/recordings
# this is called when a segment has been finalized.
gitextract__vy29lq8/
├── .dockerignore
├── .github/
│ ├── DISCUSSION_TEMPLATE/
│ │ └── questions.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug.yml
│ │ ├── config.yml
│ │ └── feature.yml
│ ├── dependabot.yml
│ └── workflows/
│ ├── lint.yml
│ ├── nightly_binaries.yml
│ ├── release.yml
│ └── test.yml
├── .gitignore
├── .golangci.yml
├── LICENSE
├── Makefile
├── README.md
├── SECURITY.md
├── api/
│ ├── .redocly.yaml
│ └── openapi.yaml
├── docker/
│ ├── ffmpeg-rpi.Dockerfile
│ ├── ffmpeg.Dockerfile
│ ├── rpi.Dockerfile
│ └── standard.Dockerfile
├── docs/
│ ├── 1-kickoff/
│ │ ├── 1-introduction.md
│ │ ├── 2-install.md
│ │ ├── 3-upgrade.md
│ │ ├── 4-basic-usage.md
│ │ └── index.md
│ ├── 2-publish/
│ │ ├── 01-overview.md
│ │ ├── 02-srt-clients.md
│ │ ├── 03-srt-cameras-and-servers.md
│ │ ├── 04-webrtc-clients.md
│ │ ├── 05-webrtc-servers.md
│ │ ├── 06-rtsp-clients.md
│ │ ├── 07-rtsp-cameras-and-servers.md
│ │ ├── 08-rtmp-clients.md
│ │ ├── 09-rtmp-cameras-and-servers.md
│ │ ├── 10-hls-cameras-and-servers.md
│ │ ├── 11-mpeg-ts.md
│ │ ├── 12-rtp.md
│ │ ├── 13-raspberry-pi-cameras.md
│ │ ├── 14-generic-webcams.md
│ │ ├── 15-ffmpeg.md
│ │ ├── 16-gstreamer.md
│ │ ├── 17-obs-studio.md
│ │ ├── 18-python-opencv.md
│ │ ├── 19-golang.md
│ │ ├── 20-unity.md
│ │ ├── 21-web-browsers.md
│ │ └── index.md
│ ├── 3-read/
│ │ ├── 01-overview.md
│ │ ├── 02-srt.md
│ │ ├── 03-webrtc.md
│ │ ├── 04-rtsp.md
│ │ ├── 05-rtmp.md
│ │ ├── 06-hls.md
│ │ ├── 07-ffmpeg.md
│ │ ├── 08-gstreamer.md
│ │ ├── 09-vlc.md
│ │ ├── 10-obs-studio.md
│ │ ├── 11-python-opencv.md
│ │ ├── 12-golang.md
│ │ ├── 13-unity.md
│ │ ├── 14-web-browsers.md
│ │ └── index.md
│ ├── 4-other/
│ │ ├── 02-configuration.md
│ │ ├── 03-authentication.md
│ │ ├── 04-remuxing-reencoding-compression.md
│ │ ├── 05-always-available.md
│ │ ├── 06-record.md
│ │ ├── 07-playback.md
│ │ ├── 08-forward.md
│ │ ├── 09-proxy.md
│ │ ├── 10-extract-snapshots.md
│ │ ├── 11-on-demand-publishing.md
│ │ ├── 12-absolute-timestamps.md
│ │ ├── 13-expose-the-server-in-a-subfolder.md
│ │ ├── 14-embed-streams-in-a-website.md
│ │ ├── 15-start-on-boot.md
│ │ ├── 16-logging.md
│ │ ├── 17-hooks.md
│ │ ├── 18-control-api.md
│ │ ├── 19-metrics.md
│ │ ├── 20-performance.md
│ │ ├── 21-srt-specific-features.md
│ │ ├── 22-webrtc-specific-features.md
│ │ ├── 23-rtsp-specific-features.md
│ │ ├── 24-rtmp-specific-features.md
│ │ ├── 25-decrease-packet-loss.md
│ │ └── index.md
│ ├── 5-references/
│ │ ├── 1-configuration-file.md
│ │ ├── 2-control-api.md
│ │ └── index.md
│ ├── 6-misc/
│ │ ├── 1-compile.md
│ │ ├── 2-license.md
│ │ ├── 3-security.md
│ │ ├── 4-specifications.md
│ │ ├── 5-related-projects.md
│ │ └── index.md
│ └── redirects.yaml
├── go.mod
├── go.sum
├── internal/
│ ├── api/
│ │ ├── api.go
│ │ ├── api_config_global.go
│ │ ├── api_config_global_test.go
│ │ ├── api_config_pathdefaults.go
│ │ ├── api_config_pathdefaults_test.go
│ │ ├── api_config_paths.go
│ │ ├── api_config_paths_test.go
│ │ ├── api_hls.go
│ │ ├── api_hls_test.go
│ │ ├── api_paths.go
│ │ ├── api_paths_test.go
│ │ ├── api_recordings.go
│ │ ├── api_recordings_test.go
│ │ ├── api_rtmp.go
│ │ ├── api_rtmp_test.go
│ │ ├── api_rtsp.go
│ │ ├── api_rtsp_test.go
│ │ ├── api_srt.go
│ │ ├── api_srt_test.go
│ │ ├── api_test.go
│ │ ├── api_webrtc.go
│ │ ├── api_webrtc_test.go
│ │ ├── paginate.go
│ │ ├── paginate_test.go
│ │ └── testdata/
│ │ └── fuzz/
│ │ └── FuzzPaginate/
│ │ ├── 23731da0f18d31d0
│ │ ├── 34523a772174e26e
│ │ └── 85649d45641911d0
│ ├── auth/
│ │ ├── credentials.go
│ │ ├── error.go
│ │ ├── jwt_claims.go
│ │ ├── manager.go
│ │ ├── manager_test.go
│ │ └── request.go
│ ├── certloader/
│ │ ├── certloader.go
│ │ └── certloader_test.go
│ ├── conf/
│ │ ├── always_available_track.go
│ │ ├── always_available_track_codec.go
│ │ ├── auth_action.go
│ │ ├── auth_internal_user.go
│ │ ├── auth_internal_user_permission.go
│ │ ├── auth_method.go
│ │ ├── conf.go
│ │ ├── conf_test.go
│ │ ├── credential.go
│ │ ├── credential_test.go
│ │ ├── decrypt/
│ │ │ └── decrypt.go
│ │ ├── duration.go
│ │ ├── duration_test.go
│ │ ├── encryption.go
│ │ ├── env/
│ │ │ ├── env.go
│ │ │ └── env_test.go
│ │ ├── global.go
│ │ ├── hls_variant.go
│ │ ├── ip_network.go
│ │ ├── ip_networks.go
│ │ ├── jsonwrapper/
│ │ │ ├── testdata/
│ │ │ │ └── fuzz/
│ │ │ │ └── FuzzUnmarshal/
│ │ │ │ ├── 297c43aee5d30530
│ │ │ │ └── 7f71a2d116d5afde
│ │ │ ├── unmarshal.go
│ │ │ └── unmarshal_test.go
│ │ ├── log_destination.go
│ │ ├── log_destinations.go
│ │ ├── log_level.go
│ │ ├── optional_global.go
│ │ ├── optional_path.go
│ │ ├── path.go
│ │ ├── path_test.go
│ │ ├── record_format.go
│ │ ├── rtsp_auth_method.go
│ │ ├── rtsp_auth_methods.go
│ │ ├── rtsp_range_type.go
│ │ ├── rtsp_transport.go
│ │ ├── rtsp_transports.go
│ │ ├── string_size.go
│ │ ├── webrtc_ice_server.go
│ │ └── yamlwrapper/
│ │ ├── testdata/
│ │ │ └── fuzz/
│ │ │ └── FuzzUnmarshal/
│ │ │ ├── 90b5d1b18dd9f8ac
│ │ │ └── dc806ec658c460fc
│ │ ├── unmarshal.go
│ │ └── unmarshal_test.go
│ ├── confwatcher/
│ │ ├── confwatcher.go
│ │ └── confwatcher_test.go
│ ├── core/
│ │ ├── api_test.go
│ │ ├── core.go
│ │ ├── core_test.go
│ │ ├── metrics_test.go
│ │ ├── path.go
│ │ ├── path_manager.go
│ │ ├── path_manager_test.go
│ │ ├── path_test.go
│ │ ├── source_redirect.go
│ │ ├── test_on_demand/
│ │ │ └── main.go
│ │ ├── upgrade.go
│ │ ├── upgrade_disabled.go
│ │ └── versiongetter/
│ │ └── main.go
│ ├── counterdumper/
│ │ ├── dumper.go
│ │ └── dumper_test.go
│ ├── defs/
│ │ ├── api.go
│ │ ├── api_hls.go
│ │ ├── api_path.go
│ │ ├── api_path_track.go
│ │ ├── api_path_track_codec.go
│ │ ├── api_path_track_codec_props.go
│ │ ├── api_path_track_codec_test.go
│ │ ├── api_recording.go
│ │ ├── api_rtmp.go
│ │ ├── api_rtsp.go
│ │ ├── api_srt.go
│ │ ├── api_webrtc.go
│ │ ├── defs.go
│ │ ├── path.go
│ │ ├── path_access_request.go
│ │ ├── publisher.go
│ │ ├── reader.go
│ │ ├── source.go
│ │ └── static_source.go
│ ├── errordumper/
│ │ ├── dumper.go
│ │ └── dumper_test.go
│ ├── externalcmd/
│ │ ├── cmd.go
│ │ ├── cmd_unix.go
│ │ ├── cmd_win.go
│ │ └── pool.go
│ ├── hooks/
│ │ ├── hooks.go
│ │ ├── on_connect.go
│ │ ├── on_demand.go
│ │ ├── on_init.go
│ │ ├── on_read.go
│ │ └── on_ready.go
│ ├── linters/
│ │ ├── conf/
│ │ │ └── conf_test.go
│ │ └── go2api/
│ │ └── go2api_test.go
│ ├── logger/
│ │ ├── destination.go
│ │ ├── destination_file.go
│ │ ├── destination_stdout.go
│ │ ├── destination_syslog.go
│ │ ├── destination_syslog_disabled.go
│ │ ├── level.go
│ │ ├── logger.go
│ │ ├── logger_test.go
│ │ └── writer.go
│ ├── metrics/
│ │ ├── metrics.go
│ │ └── metrics_test.go
│ ├── ntpestimator/
│ │ ├── estimator.go
│ │ └── estimator_test.go
│ ├── packetdumper/
│ │ ├── conn.go
│ │ ├── conn_test.go
│ │ ├── dial_context.go
│ │ ├── listen.go
│ │ ├── listen_packet.go
│ │ ├── listener.go
│ │ ├── packet_conn.go
│ │ └── packet_conn_test.go
│ ├── playback/
│ │ ├── muxer.go
│ │ ├── muxer_fmp4.go
│ │ ├── muxer_mp4.go
│ │ ├── muxer_mp4_test.go
│ │ ├── on_get.go
│ │ ├── on_get_test.go
│ │ ├── on_list.go
│ │ ├── on_list_test.go
│ │ ├── segment_fmp4.go
│ │ ├── segment_fmp4_test.go
│ │ ├── server.go
│ │ └── server_test.go
│ ├── pprof/
│ │ ├── pprof.go
│ │ └── pprof_test.go
│ ├── protocols/
│ │ ├── hls/
│ │ │ ├── from_stream.go
│ │ │ ├── from_stream_test.go
│ │ │ ├── to_stream.go
│ │ │ └── to_stream_test.go
│ │ ├── httpp/
│ │ │ ├── content_type.go
│ │ │ ├── credentials.go
│ │ │ ├── credentials_test.go
│ │ │ ├── handler_exit_on_panic.go
│ │ │ ├── handler_filter_requests.go
│ │ │ ├── handler_filter_requests_test.go
│ │ │ ├── handler_logger.go
│ │ │ ├── handler_origin.go
│ │ │ ├── handler_origin_test.go
│ │ │ ├── handler_server_header.go
│ │ │ ├── handler_tracker.go
│ │ │ ├── handler_tracker_test.go
│ │ │ ├── handler_write_timeout.go
│ │ │ ├── remote_addr.go
│ │ │ ├── server.go
│ │ │ └── server_test.go
│ │ ├── mpegts/
│ │ │ ├── enhanced_reader.go
│ │ │ ├── from_stream.go
│ │ │ ├── from_stream_test.go
│ │ │ ├── to_stream.go
│ │ │ └── to_stream_test.go
│ │ ├── rtmp/
│ │ │ ├── from_stream.go
│ │ │ ├── from_stream_test.go
│ │ │ ├── to_stream.go
│ │ │ └── to_stream_test.go
│ │ ├── rtsp/
│ │ │ ├── credentials.go
│ │ │ ├── credentials_test.go
│ │ │ └── to_stream.go
│ │ ├── tls/
│ │ │ ├── make_config.go
│ │ │ └── make_config_test.go
│ │ ├── udp/
│ │ │ ├── listener.go
│ │ │ ├── listener_test.go
│ │ │ └── params.go
│ │ ├── unix/
│ │ │ ├── listener.go
│ │ │ ├── listener_test.go
│ │ │ └── params.go
│ │ ├── webrtc/
│ │ │ ├── from_stream.go
│ │ │ ├── from_stream_test.go
│ │ │ ├── incoming_track.go
│ │ │ ├── net.go
│ │ │ ├── outgoing_data_channel.go
│ │ │ ├── outgoing_track.go
│ │ │ ├── peer_connection.go
│ │ │ ├── peer_connection_test.go
│ │ │ ├── stats.go
│ │ │ ├── stats_interceptor.go
│ │ │ ├── tcp_mux_wrapper.go
│ │ │ ├── to_stream.go
│ │ │ └── to_stream_test.go
│ │ ├── websocket/
│ │ │ ├── serverconn.go
│ │ │ └── serverconn_test.go
│ │ └── whip/
│ │ ├── client.go
│ │ ├── client_test.go
│ │ ├── ice_fragment.go
│ │ ├── ice_fragment_test.go
│ │ ├── link_header.go
│ │ └── link_header_test.go
│ ├── recordcleaner/
│ │ ├── cleaner.go
│ │ └── cleaner_test.go
│ ├── recorder/
│ │ ├── format.go
│ │ ├── format_fmp4.go
│ │ ├── format_fmp4_part.go
│ │ ├── format_fmp4_segment.go
│ │ ├── format_fmp4_track.go
│ │ ├── format_mpegts.go
│ │ ├── format_mpegts_segment.go
│ │ ├── format_mpegts_track.go
│ │ ├── recorder.go
│ │ ├── recorder_instance.go
│ │ └── recorder_test.go
│ ├── recordstore/
│ │ ├── mp4_boxes.go
│ │ ├── path.go
│ │ ├── path_test.go
│ │ ├── recordstore.go
│ │ ├── segment.go
│ │ └── segment_test.go
│ ├── restrictnetwork/
│ │ └── restrict_network.go
│ ├── rlimit/
│ │ ├── rlimit_unix.go
│ │ └── rlimit_win.go
│ ├── servers/
│ │ ├── hls/
│ │ │ ├── hlsjsdownloader/
│ │ │ │ ├── HASH
│ │ │ │ ├── VERSION
│ │ │ │ └── main.go
│ │ │ ├── http_server.go
│ │ │ ├── index.html
│ │ │ ├── muxer.go
│ │ │ ├── muxer_instance.go
│ │ │ ├── server.go
│ │ │ └── server_test.go
│ │ ├── rtmp/
│ │ │ ├── conn.go
│ │ │ ├── listener.go
│ │ │ ├── server.go
│ │ │ └── server_test.go
│ │ ├── rtsp/
│ │ │ ├── conn.go
│ │ │ ├── mpegts_demuxer.go
│ │ │ ├── server.go
│ │ │ ├── server_test.go
│ │ │ └── session.go
│ │ ├── srt/
│ │ │ ├── conn.go
│ │ │ ├── listener.go
│ │ │ ├── server.go
│ │ │ ├── server_test.go
│ │ │ ├── streamid.go
│ │ │ └── streamid_test.go
│ │ └── webrtc/
│ │ ├── http_server.go
│ │ ├── publish_index.html
│ │ ├── publisher.js
│ │ ├── read_index.html
│ │ ├── reader.js
│ │ ├── server.go
│ │ ├── server_test.go
│ │ └── session.go
│ ├── staticsources/
│ │ ├── handler.go
│ │ ├── hls/
│ │ │ ├── source.go
│ │ │ └── source_test.go
│ │ ├── mpegts/
│ │ │ ├── source.go
│ │ │ └── source_test.go
│ │ ├── rpicamera/
│ │ │ ├── camera_arm32_.go
│ │ │ ├── camera_arm64_.go
│ │ │ ├── camera_arm_.go
│ │ │ ├── camera_other.go
│ │ │ ├── downloader.go
│ │ │ ├── mtxrpicamdownloader/
│ │ │ │ ├── HASH_MTXRPICAM_32_TAR_GZ
│ │ │ │ ├── HASH_MTXRPICAM_64_TAR_GZ
│ │ │ │ ├── VERSION
│ │ │ │ └── main.go
│ │ │ ├── params.go
│ │ │ ├── params_serialize.go
│ │ │ ├── pipe.go
│ │ │ └── source.go
│ │ ├── rtmp/
│ │ │ ├── source.go
│ │ │ └── source_test.go
│ │ ├── rtp/
│ │ │ ├── format.go
│ │ │ ├── media.go
│ │ │ ├── source.go
│ │ │ └── source_test.go
│ │ ├── rtsp/
│ │ │ ├── source.go
│ │ │ └── source_test.go
│ │ ├── srt/
│ │ │ ├── source.go
│ │ │ └── source_test.go
│ │ └── webrtc/
│ │ ├── source.go
│ │ └── source_test.go
│ ├── stream/
│ │ ├── format_updater.go
│ │ ├── offline_sub_stream.go
│ │ ├── offline_sub_stream_track.go
│ │ ├── reader.go
│ │ ├── rtp_decoder.go
│ │ ├── rtp_encoder.go
│ │ ├── stream.go
│ │ ├── stream_alwaysavailable_test.go
│ │ ├── stream_format.go
│ │ ├── stream_media.go
│ │ ├── stream_standard_test.go
│ │ ├── sub_stream.go
│ │ ├── sub_stream_format.go
│ │ ├── sub_stream_media.go
│ │ └── unit_remuxer.go
│ ├── test/
│ │ ├── auth_manager.go
│ │ ├── formats.go
│ │ ├── logger.go
│ │ ├── medias.go
│ │ ├── path_manager.go
│ │ ├── static_source_parent.go
│ │ ├── temp_file.go
│ │ └── tls_cert.go
│ ├── teste2e/
│ │ ├── build_images_test.go
│ │ ├── hls_manager_test.go
│ │ ├── images/
│ │ │ ├── ffmpeg/
│ │ │ │ ├── Dockerfile
│ │ │ │ ├── emptyvideo.mkv
│ │ │ │ ├── emptyvideoaudio.mkv
│ │ │ │ └── start.sh
│ │ │ ├── gstreamer/
│ │ │ │ ├── Dockerfile
│ │ │ │ ├── emptyvideo.mkv
│ │ │ │ ├── exitafterframe.c
│ │ │ │ └── start.sh
│ │ │ └── vlc/
│ │ │ ├── Dockerfile
│ │ │ └── start.sh
│ │ ├── rtsp_server_test.go
│ │ └── tests_test.go
│ └── unit/
│ ├── payload.go
│ ├── payload_ac3.go
│ ├── payload_av1.go
│ ├── payload_g711.go
│ ├── payload_h264.go
│ ├── payload_h265.go
│ ├── payload_klv.go
│ ├── payload_lpcm.go
│ ├── payload_mjpeg.go
│ ├── payload_mpeg1_audio.go
│ ├── payload_mpeg1_video.go
│ ├── payload_mpeg4_audio.go
│ ├── payload_mpeg4_audio_latm.go
│ ├── payload_mpeg4_video.go
│ ├── payload_opus.go
│ ├── payload_vp8.go
│ ├── payload_vp9.go
│ └── unit.go
├── main.go
├── mediamtx.yml
└── scripts/
├── binaries.mk
├── dockerhub.mk
├── format.mk
├── lint.mk
├── test-e2e.mk
├── test.mk
└── winres.json
SYMBOL INDEX (2116 symbols across 332 files)
FILE: internal/api/api.go
function interfaceIsEmpty (line 22) | func interfaceIsEmpty(i any) bool {
function sortedKeys (line 26) | func sortedKeys(paths map[string]*conf.Path) []string {
function paramName (line 37) | func paramName(ctx *gin.Context) (string, bool) {
function recordingsOfPath (line 47) | func recordingsOfPath(
type apiAuthManager (line 68) | type apiAuthManager interface
type apiParent (line 73) | type apiParent interface
type API (line 79) | type API struct
method Initialize (line 108) | func (a *API) Initialize() error {
method Close (line 210) | func (a *API) Close() {
method Log (line 216) | func (a *API) Log(level logger.Level, format string, args ...any) {
method writeError (line 220) | func (a *API) writeError(ctx *gin.Context, status int, err error) {
method writeOK (line 231) | func (a *API) writeOK(ctx *gin.Context) {
method middlewarePreflightRequests (line 235) | func (a *API) middlewarePreflightRequests(ctx *gin.Context) {
method middlewareAuth (line 245) | func (a *API) middlewareAuth(ctx *gin.Context) {
method onInfo (line 277) | func (a *API) onInfo(ctx *gin.Context) {
method onAuthJwksRefresh (line 284) | func (a *API) onAuthJwksRefresh(ctx *gin.Context) {
method ReloadConf (line 290) | func (a *API) ReloadConf(conf *conf.Conf) {
FILE: internal/api/api_config_global.go
method onConfigGlobalGet (line 11) | func (a *API) onConfigGlobalGet(ctx *gin.Context) {
method onConfigGlobalPatch (line 19) | func (a *API) onConfigGlobalPatch(ctx *gin.Context) {
FILE: internal/api/api_config_global_test.go
function TestConfigGlobalGet (line 16) | func TestConfigGlobalGet(t *testing.T) {
function TestConfigGlobalPatch (line 51) | func TestConfigGlobalPatch(t *testing.T) {
function TestConfigGlobalPatchUnknownField (line 88) | func TestConfigGlobalPatchUnknownField(t *testing.T) { //nolint:dupl
FILE: internal/api/api_config_pathdefaults.go
method onConfigPathDefaultsGet (line 11) | func (a *API) onConfigPathDefaultsGet(ctx *gin.Context) {
method onConfigPathDefaultsPatch (line 19) | func (a *API) onConfigPathDefaultsPatch(ctx *gin.Context) {
FILE: internal/api/api_config_pathdefaults_test.go
function TestConfigPathDefaultsGet (line 13) | func TestConfigPathDefaultsGet(t *testing.T) {
function TestConfigPathDefaultsPatch (line 37) | func TestConfigPathDefaultsPatch(t *testing.T) {
FILE: internal/api/api_config_paths.go
method onConfigPathsList (line 14) | func (a *API) onConfigPathsList(ctx *gin.Context) {
method onConfigPathsGet (line 38) | func (a *API) onConfigPathsGet(ctx *gin.Context) {
method onConfigPathsAdd (line 58) | func (a *API) onConfigPathsAdd(ctx *gin.Context) { //nolint:dupl
method onConfigPathsPatch (line 95) | func (a *API) onConfigPathsPatch(ctx *gin.Context) { //nolint:dupl
method onConfigPathsReplace (line 136) | func (a *API) onConfigPathsReplace(ctx *gin.Context) { //nolint:dupl
method onConfigPathsDelete (line 177) | func (a *API) onConfigPathsDelete(ctx *gin.Context) {
FILE: internal/api/api_config_paths_test.go
function TestConfigPathsList (line 15) | func TestConfigPathsList(t *testing.T) {
function TestConfigPathsGet (line 61) | func TestConfigPathsGet(t *testing.T) {
function TestConfigPathsAdd (line 90) | func TestConfigPathsAdd(t *testing.T) {
function TestConfigPathsAddUnknownField (line 125) | func TestConfigPathsAddUnknownField(t *testing.T) { //nolint:dupl
function TestConfigPathsPatch (line 163) | func TestConfigPathsPatch(t *testing.T) { //nolint:dupl
function TestConfigPathsReplace (line 204) | func TestConfigPathsReplace(t *testing.T) { //nolint:dupl
function TestConfigPathsReplaceNonExisting (line 245) | func TestConfigPathsReplaceNonExisting(t *testing.T) { //nolint:dupl
function TestConfigPathsDelete (line 278) | func TestConfigPathsDelete(t *testing.T) {
FILE: internal/api/api_hls.go
method onHLSMuxersList (line 13) | func (a *API) onHLSMuxersList(ctx *gin.Context) {
method onHLSMuxersGet (line 31) | func (a *API) onHLSMuxersGet(ctx *gin.Context) {
FILE: internal/api/api_hls_test.go
type testHLSServer (line 15) | type testHLSServer struct
method APIMuxersList (line 19) | func (s *testHLSServer) APIMuxersList() (*defs.APIHLSMuxerList, error) {
method APIMuxersGet (line 27) | func (s *testHLSServer) APIMuxersGet(name string) (*defs.APIHLSMuxer, ...
function TestHLSMuxersList (line 35) | func TestHLSMuxersList(t *testing.T) {
function TestHLSMuxersGet (line 82) | func TestHLSMuxersGet(t *testing.T) {
FILE: internal/api/api_paths.go
method onPathsList (line 13) | func (a *API) onPathsList(ctx *gin.Context) {
method onPathsGet (line 31) | func (a *API) onPathsGet(ctx *gin.Context) {
FILE: internal/api/api_paths_test.go
type testPathManager (line 14) | type testPathManager struct
method APIPathsList (line 18) | func (m *testPathManager) APIPathsList() (*defs.APIPathList, error) {
method APIPathsGet (line 26) | func (m *testPathManager) APIPathsGet(name string) (*defs.APIPath, err...
function TestPathsList (line 34) | func TestPathsList(t *testing.T) {
function TestPathsGet (line 93) | func TestPathsGet(t *testing.T) {
FILE: internal/api/api_recordings.go
method onRecordingsList (line 16) | func (a *API) onRecordingsList(ctx *gin.Context) {
method onRecordingsGet (line 43) | func (a *API) onRecordingsGet(ctx *gin.Context) {
method onRecordingDeleteSegment (line 63) | func (a *API) onRecordingDeleteSegment(ctx *gin.Context) {
FILE: internal/api/api_recordings_test.go
function TestRecordingsList (line 16) | func TestRecordingsList(t *testing.T) {
function TestRecordingsGet (line 87) | func TestRecordingsGet(t *testing.T) {
function TestRecordingsDeleteSegment (line 137) | func TestRecordingsDeleteSegment(t *testing.T) {
FILE: internal/api/api_rtmp.go
method onRTMPConnsList (line 12) | func (a *API) onRTMPConnsList(ctx *gin.Context) {
method onRTMPConnsGet (line 30) | func (a *API) onRTMPConnsGet(ctx *gin.Context) {
method onRTMPConnsKick (line 50) | func (a *API) onRTMPConnsKick(ctx *gin.Context) {
method onRTMPSConnsList (line 70) | func (a *API) onRTMPSConnsList(ctx *gin.Context) {
method onRTMPSConnsGet (line 88) | func (a *API) onRTMPSConnsGet(ctx *gin.Context) {
method onRTMPSConnsKick (line 108) | func (a *API) onRTMPSConnsKick(ctx *gin.Context) {
FILE: internal/api/api_rtmp_test.go
type testRTMPServer (line 17) | type testRTMPServer struct
method APIConnsList (line 21) | func (s *testRTMPServer) APIConnsList() (*defs.APIRTMPConnList, error) {
method APIConnsGet (line 29) | func (s *testRTMPServer) APIConnsGet(id uuid.UUID) (*defs.APIRTMPConn,...
method APIConnsKick (line 37) | func (s *testRTMPServer) APIConnsKick(id uuid.UUID) error {
function TestRTMPConnsList (line 45) | func TestRTMPConnsList(t *testing.T) {
function TestRTMPConnsGet (line 130) | func TestRTMPConnsGet(t *testing.T) {
function TestRTMPConnsKick (line 209) | func TestRTMPConnsKick(t *testing.T) {
FILE: internal/api/api_rtsp.go
method onRTSPConnsList (line 12) | func (a *API) onRTSPConnsList(ctx *gin.Context) {
method onRTSPConnsGet (line 30) | func (a *API) onRTSPConnsGet(ctx *gin.Context) {
method onRTSPSessionsList (line 50) | func (a *API) onRTSPSessionsList(ctx *gin.Context) {
method onRTSPSessionsGet (line 68) | func (a *API) onRTSPSessionsGet(ctx *gin.Context) {
method onRTSPSessionsKick (line 88) | func (a *API) onRTSPSessionsKick(ctx *gin.Context) {
method onRTSPSConnsList (line 108) | func (a *API) onRTSPSConnsList(ctx *gin.Context) {
method onRTSPSConnsGet (line 126) | func (a *API) onRTSPSConnsGet(ctx *gin.Context) {
method onRTSPSSessionsList (line 146) | func (a *API) onRTSPSSessionsList(ctx *gin.Context) {
method onRTSPSSessionsGet (line 164) | func (a *API) onRTSPSSessionsGet(ctx *gin.Context) {
method onRTSPSSessionsKick (line 184) | func (a *API) onRTSPSSessionsKick(ctx *gin.Context) {
FILE: internal/api/api_rtsp_test.go
type testRTSPServer (line 18) | type testRTSPServer struct
method APIConnsList (line 23) | func (s *testRTSPServer) APIConnsList() (*defs.APIRTSPConnsList, error) {
method APIConnsGet (line 31) | func (s *testRTSPServer) APIConnsGet(id uuid.UUID) (*defs.APIRTSPConn,...
method APISessionsList (line 39) | func (s *testRTSPServer) APISessionsList() (*defs.APIRTSPSessionList, ...
method APISessionsGet (line 47) | func (s *testRTSPServer) APISessionsGet(id uuid.UUID) (*defs.APIRTSPSe...
method APISessionsKick (line 55) | func (s *testRTSPServer) APISessionsKick(id uuid.UUID) error {
function TestRTSPConnsList (line 63) | func TestRTSPConnsList(t *testing.T) {
function TestRTSPConnsGet (line 154) | func TestRTSPConnsGet(t *testing.T) {
function TestRTSPSessionsList (line 237) | func TestRTSPSessionsList(t *testing.T) {
function TestRTSPSessionsGet (line 369) | func TestRTSPSessionsGet(t *testing.T) {
function TestRTSPSessionsKick (line 478) | func TestRTSPSessionsKick(t *testing.T) {
FILE: internal/api/api_srt.go
method onSRTConnsList (line 13) | func (a *API) onSRTConnsList(ctx *gin.Context) {
method onSRTConnsGet (line 31) | func (a *API) onSRTConnsGet(ctx *gin.Context) {
method onSRTConnsKick (line 51) | func (a *API) onSRTConnsKick(ctx *gin.Context) {
FILE: internal/api/api_srt_test.go
type testSRTServer (line 17) | type testSRTServer struct
method APIConnsList (line 21) | func (s *testSRTServer) APIConnsList() (*defs.APISRTConnList, error) {
method APIConnsGet (line 29) | func (s *testSRTServer) APIConnsGet(id uuid.UUID) (*defs.APISRTConn, e...
method APIConnsKick (line 37) | func (s *testSRTServer) APIConnsKick(id uuid.UUID) error {
function TestSRTConnsList (line 45) | func TestSRTConnsList(t *testing.T) {
function TestSRTConnsGet (line 115) | func TestSRTConnsGet(t *testing.T) {
function TestSRTConnsKick (line 217) | func TestSRTConnsKick(t *testing.T) {
FILE: internal/api/api_test.go
type testParent (line 21) | type testParent struct
method Log (line 25) | func (p testParent) Log(l logger.Level, s string, a ...any) {
method APIConfigSet (line 31) | func (testParent) APIConfigSet(_ *conf.Conf) {}
function tempConf (line 33) | func tempConf(t *testing.T, cnt string) *conf.Conf {
function httpRequest (line 44) | func httpRequest(t *testing.T, hc *http.Client, method string, ur string...
function checkError (line 76) | func checkError(t *testing.T, body io.Reader, msg string) {
function checkOK (line 83) | func checkOK(t *testing.T, body io.Reader) {
function TestPreflightRequest (line 90) | func TestPreflightRequest(t *testing.T) {
function TestInfo (line 128) | func TestInfo(t *testing.T) {
function TestAuthJWKSRefresh (line 157) | func TestAuthJWKSRefresh(t *testing.T) {
function TestAuthError (line 190) | func TestAuthError(t *testing.T) {
FILE: internal/api/api_webrtc.go
method onWebRTCSessionsList (line 13) | func (a *API) onWebRTCSessionsList(ctx *gin.Context) {
method onWebRTCSessionsGet (line 31) | func (a *API) onWebRTCSessionsGet(ctx *gin.Context) {
method onWebRTCSessionsKick (line 51) | func (a *API) onWebRTCSessionsKick(ctx *gin.Context) {
FILE: internal/api/api_webrtc_test.go
type testWebRTCServer (line 17) | type testWebRTCServer struct
method APISessionsList (line 21) | func (s *testWebRTCServer) APISessionsList() (*defs.APIWebRTCSessionLi...
method APISessionsGet (line 29) | func (s *testWebRTCServer) APISessionsGet(id uuid.UUID) (*defs.APIWebR...
method APISessionsKick (line 37) | func (s *testWebRTCServer) APISessionsKick(id uuid.UUID) error {
function TestWebRTCSessionsList (line 45) | func TestWebRTCSessionsList(t *testing.T) {
function TestWebRTCSessionsGet (line 135) | func TestWebRTCSessionsGet(t *testing.T) {
function TestWebRTCSessionsKick (line 211) | func TestWebRTCSessionsKick(t *testing.T) {
FILE: internal/api/paginate.go
function paginate2 (line 9) | func paginate2(itemsPtr any, itemsPerPage int, page int) int {
function paginate (line 31) | func paginate(itemsPtr any, itemsPerPageStr string, pageStr string) (int...
FILE: internal/api/paginate_test.go
function TestPaginate (line 9) | func TestPaginate(t *testing.T) {
function FuzzPaginate (line 56) | func FuzzPaginate(f *testing.F) {
FILE: internal/auth/credentials.go
type Credentials (line 4) | type Credentials struct
FILE: internal/auth/error.go
type Error (line 4) | type Error struct
method Error (line 10) | func (e Error) Error() string {
FILE: internal/auth/jwt_claims.go
type jwtClaims (line 12) | type jwtClaims struct
method UnmarshalJSON (line 18) | func (c *jwtClaims) UnmarshalJSON(b []byte) error {
FILE: internal/auth/manager.go
constant PauseAfterError (line 25) | PauseAfterError = 2 * time.Second
constant jwksRefreshPeriod (line 27) | jwksRefreshPeriod = 60 * 60 * time.Second
function isHTTP (line 30) | func isHTTP(req *Request) bool {
function matchesPermission (line 38) | func matchesPermission(perms []conf.AuthInternalUserPermission, req *Req...
type Manager (line 67) | type Manager struct
method ReloadInternalUsers (line 88) | func (m *Manager) ReloadInternalUsers(u []conf.AuthInternalUser) {
method Authenticate (line 96) | func (m *Manager) Authenticate(req *Request) (string, *Error) {
method authenticateInternal (line 121) | func (m *Manager) authenticateInternal(req *Request) (string, error) {
method authenticateWithUser (line 134) | func (m *Manager) authenticateWithUser(
method authenticateHTTP (line 161) | func (m *Manager) authenticateHTTP(req *Request) (string, error) {
method authenticateJWT (line 220) | func (m *Manager) authenticateJWT(req *Request) (string, error) {
method pullJWTJWKS (line 279) | func (m *Manager) pullJWTJWKS() (jwt.Keyfunc, error) {
method RefreshJWTJWKS (line 326) | func (m *Manager) RefreshJWTJWKS() {
FILE: internal/auth/manager_test.go
function mustParseCIDR (line 72) | func mustParseCIDR(v string) conf.IPNetwork {
function TestAuthInternal (line 83) | func TestAuthInternal(t *testing.T) {
function TestAuthInternalCustomVerifyFunc (line 223) | func TestAuthInternalCustomVerifyFunc(t *testing.T) {
function TestAuthHTTP (line 266) | func TestAuthHTTP(t *testing.T) {
function TestAuthHTTPFingerprint (line 371) | func TestAuthHTTPFingerprint(t *testing.T) {
function TestAuthHTTPExclude (line 428) | func TestAuthHTTPExclude(t *testing.T) {
function TestAuthJWT (line 452) | func TestAuthJWT(t *testing.T) {
function TestAuthJWTExclude (line 598) | func TestAuthJWTExclude(t *testing.T) {
function TestAuthJWTIssuer (line 619) | func TestAuthJWTIssuer(t *testing.T) {
function TestAuthJWTAudience (line 727) | func TestAuthJWTAudience(t *testing.T) {
function TestAuthJWTRefresh (line 841) | func TestAuthJWTRefresh(t *testing.T) {
function TestAuthJWTFingerprint (line 930) | func TestAuthJWTFingerprint(t *testing.T) {
FILE: internal/auth/request.go
type Protocol (line 11) | type Protocol
constant ProtocolRTSP (line 15) | ProtocolRTSP Protocol = "rtsp"
constant ProtocolRTMP (line 16) | ProtocolRTMP Protocol = "rtmp"
constant ProtocolHLS (line 17) | ProtocolHLS Protocol = "hls"
constant ProtocolWebRTC (line 18) | ProtocolWebRTC Protocol = "webrtc"
constant ProtocolSRT (line 19) | ProtocolSRT Protocol = "srt"
type Request (line 23) | type Request struct
FILE: internal/certloader/certloader.go
type CertLoader (line 13) | type CertLoader struct
method Initialize (line 26) | func (cl *CertLoader) Initialize() error {
method Close (line 57) | func (cl *CertLoader) Close() {
method GetCertificate (line 67) | func (cl *CertLoader) GetCertificate() func(*tls.ClientHelloInfo) (*tl...
method watch (line 75) | func (cl *CertLoader) watch() {
FILE: internal/certloader/certloader_test.go
function TestCertReload (line 13) | func TestCertReload(t *testing.T) {
FILE: internal/conf/always_available_track.go
type AlwaysAvailableTrack (line 10) | type AlwaysAvailableTrack struct
method UnmarshalJSON (line 18) | func (t *AlwaysAvailableTrack) UnmarshalJSON(b []byte) error {
FILE: internal/conf/always_available_track_codec.go
type AlwaysAvailableTrackCodec (line 6) | type AlwaysAvailableTrackCodec
method UnmarshalEnv (line 21) | func (d *AlwaysAvailableTrackCodec) UnmarshalEnv(_ string, v string) e...
constant CodecAV1 (line 10) | CodecAV1 AlwaysAvailableTrackCodec = "AV1"
constant CodecVP9 (line 11) | CodecVP9 AlwaysAvailableTrackCodec = "VP9"
constant CodecH265 (line 12) | CodecH265 AlwaysAvailableTrackCodec = "H265"
constant CodecH264 (line 13) | CodecH264 AlwaysAvailableTrackCodec = "H264"
constant CodecMPEG4Audio (line 14) | CodecMPEG4Audio AlwaysAvailableTrackCodec = "MPEG4Audio"
constant CodecOpus (line 15) | CodecOpus AlwaysAvailableTrackCodec = "Opus"
constant CodecG711 (line 16) | CodecG711 AlwaysAvailableTrackCodec = "G711"
constant CodecLPCM (line 17) | CodecLPCM AlwaysAvailableTrackCodec = "LPCM"
FILE: internal/conf/auth_action.go
type AuthAction (line 10) | type AuthAction
method UnmarshalJSON (line 23) | func (d *AuthAction) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 46) | func (d *AuthAction) UnmarshalEnv(_ string, v string) error {
constant AuthActionPublish (line 14) | AuthActionPublish AuthAction = "publish"
constant AuthActionRead (line 15) | AuthActionRead AuthAction = "read"
constant AuthActionPlayback (line 16) | AuthActionPlayback AuthAction = "playback"
constant AuthActionAPI (line 17) | AuthActionAPI AuthAction = "api"
constant AuthActionMetrics (line 18) | AuthActionMetrics AuthAction = "metrics"
constant AuthActionPprof (line 19) | AuthActionPprof AuthAction = "pprof"
FILE: internal/conf/auth_internal_user.go
type AuthInternalUser (line 4) | type AuthInternalUser struct
FILE: internal/conf/auth_internal_user_permission.go
type AuthInternalUserPermission (line 4) | type AuthInternalUserPermission struct
FILE: internal/conf/auth_method.go
type AuthMethod (line 10) | type AuthMethod
method UnmarshalJSON (line 20) | func (d *AuthMethod) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 37) | func (d *AuthMethod) UnmarshalEnv(_ string, v string) error {
constant AuthMethodInternal (line 14) | AuthMethodInternal AuthMethod = "internal"
constant AuthMethodHTTP (line 15) | AuthMethodHTTP AuthMethod = "http"
constant AuthMethodJWT (line 16) | AuthMethodJWT AuthMethod = "jwt"
FILE: internal/conf/conf.go
function sortedKeys (line 28) | func sortedKeys(paths map[string]*OptionalPath) []string {
function firstThatExists (line 39) | func firstThatExists(paths []string) string {
function setAllNilSlicesToEmptyRecursive (line 49) | func setAllNilSlicesToEmptyRecursive(rv reflect.Value) {
function copyStructFields (line 92) | func copyStructFields(dest any, source any) {
function mustParseCIDR (line 119) | func mustParseCIDR(v string) IPNetwork {
function anyPathHasDeprecatedCredentials (line 130) | func anyPathHasDeprecatedCredentials(pathDefaults Path, paths map[string...
function deepClone (line 156) | func deepClone(rv reflect.Value) reflect.Value {
type nilLogger (line 202) | type nilLogger struct
method Log (line 204) | func (nilLogger) Log(_ logger.Level, _ string, _ ...any) {
type Conf (line 242) | type Conf struct
method setDefaults (line 413) | func (conf *Conf) setDefaults() {
method loadFromFile (line 561) | func (conf *Conf) loadFromFile(fpath string, defaultConfPaths []string...
method Clone (line 600) | func (conf Conf) Clone() *Conf {
method Validate (line 606) | func (conf *Conf) Validate(l logger.Writer) error {
method Global (line 1093) | func (conf *Conf) Global() *Global {
method PatchGlobal (line 1102) | func (conf *Conf) PatchGlobal(optional *OptionalGlobal) {
method PatchPathDefaults (line 1107) | func (conf *Conf) PatchPathDefaults(optional *OptionalPath) {
method AddPath (line 1112) | func (conf *Conf) AddPath(name string, p *OptionalPath) error {
method PatchPath (line 1126) | func (conf *Conf) PatchPath(name string, optional2 *OptionalPath) error {
method ReplacePath (line 1137) | func (conf *Conf) ReplacePath(name string, optional2 *OptionalPath) er...
method RemovePath (line 1147) | func (conf *Conf) RemovePath(name string) error {
function Load (line 530) | func Load(fpath string, defaultConfPaths []string, l logger.Writer) (*Co...
FILE: internal/conf/conf_test.go
function createTempFile (line 18) | func createTempFile(byts []byte) (string, error) {
function TestConfFromFile (line 33) | func TestConfFromFile(t *testing.T) {
function TestConfFromFileAndEnv (line 125) | func TestConfFromFileAndEnv(t *testing.T) {
function TestConfFromEnvOnly (line 158) | func TestConfFromEnvOnly(t *testing.T) {
function TestConfEncryption (line 170) | func TestConfEncryption(t *testing.T) {
function TestConfDeprecatedAuth (line 205) | func TestConfDeprecatedAuth(t *testing.T) {
function TestConfErrors (line 265) | func TestConfErrors(t *testing.T) {
function TestAlwaysAvailableFileErrorMagicBytes (line 762) | func TestAlwaysAvailableFileErrorMagicBytes(t *testing.T) {
function TestSampleConfFile (line 778) | func TestSampleConfFile(t *testing.T) {
function TestClone (line 810) | func TestClone(t *testing.T) {
FILE: internal/conf/credential.go
constant plainCredentialSupportedChars (line 19) | plainCredentialSupportedChars = "A-Z,0-9,!,$,(,),*,+,.,;,<,=,>,[,],^,_,-...
function sha256Base64 (line 21) | func sha256Base64(in string) string {
type Credential (line 28) | type Credential
method UnmarshalJSON (line 31) | func (d *Credential) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 43) | func (d *Credential) UnmarshalEnv(_ string, v string) error {
method IsSha256 (line 48) | func (d Credential) IsSha256() bool {
method IsArgon2 (line 53) | func (d Credential) IsArgon2() bool {
method IsHashed (line 58) | func (d Credential) IsHashed() bool {
method Check (line 63) | func (d Credential) Check(guess string) bool {
method validate (line 82) | func (d Credential) validate() error {
FILE: internal/conf/credential_test.go
function TestCredential (line 9) | func TestCredential(t *testing.T) {
FILE: internal/conf/decrypt/decrypt.go
function Decrypt (line 12) | func Decrypt(key string, byts []byte) ([]byte, error) {
FILE: internal/conf/duration.go
type Duration (line 17) | type Duration
method marshalInternal (line 19) | func (d Duration) marshalInternal() string {
method MarshalJSON (line 47) | func (d Duration) MarshalJSON() ([]byte, error) {
method unmarshalInternal (line 51) | func (d *Duration) unmarshalInternal(in string) error {
method UnmarshalJSON (line 86) | func (d *Duration) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 101) | func (d *Duration) UnmarshalEnv(_ string, v string) error {
FILE: internal/conf/duration_test.go
function TestDurationUnmarshal (line 37) | func TestDurationUnmarshal(t *testing.T) {
function TestDurationMarshal (line 48) | func TestDurationMarshal(t *testing.T) {
FILE: internal/conf/encryption.go
type Encryption (line 10) | type Encryption
method UnmarshalJSON (line 20) | func (d *Encryption) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 44) | func (d *Encryption) UnmarshalEnv(_ string, v string) error {
constant EncryptionNo (line 14) | EncryptionNo Encryption = "no"
constant EncryptionOptional (line 15) | EncryptionOptional Encryption = "optional"
constant EncryptionStrict (line 16) | EncryptionStrict Encryption = "strict"
FILE: internal/conf/env/env.go
type Unmarshaler (line 13) | type Unmarshaler interface
function envHasAtLeastAKeyWithPrefix (line 17) | func envHasAtLeastAKeyWithPrefix(env map[string]string, prefix string) b...
function loadEnvInternal (line 26) | func loadEnvInternal(env map[string]string, prefix string, prv reflect.V...
function loadWithEnv (line 281) | func loadWithEnv(env map[string]string, prefix string, v any) error {
function envToMap (line 285) | func envToMap() map[string]string {
function Load (line 295) | func Load(prefix string, v any) error {
FILE: internal/conf/env/env_test.go
function ptrOf (line 11) | func ptrOf[T any](v T) *T {
type myDuration (line 17) | type myDuration
method UnmarshalJSON (line 19) | func (d *myDuration) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 35) | func (d *myDuration) UnmarshalEnv(_ string, v string) error {
function TestLoadPrimitives (line 39) | func TestLoadPrimitives(t *testing.T) {
function TestLoadSlice (line 118) | func TestLoadSlice(t *testing.T) {
function TestLoadSliceStruct (line 148) | func TestLoadSliceStruct(t *testing.T) {
function TestLoadEmptySliceStruct (line 195) | func TestLoadEmptySliceStruct(t *testing.T) {
function TestLoadPreloadedSliceStruct (line 219) | func TestLoadPreloadedSliceStruct(t *testing.T) {
FILE: internal/conf/global.go
function newGlobalValues (line 29) | func newGlobalValues() any {
type Global (line 34) | type Global struct
method MarshalJSON (line 39) | func (p *Global) MarshalJSON() ([]byte, error) {
FILE: internal/conf/hls_variant.go
type HLSVariant (line 12) | type HLSVariant
method MarshalJSON (line 15) | func (d HLSVariant) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 33) | func (d *HLSVariant) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 57) | func (d *HLSVariant) UnmarshalEnv(_ string, v string) error {
FILE: internal/conf/ip_network.go
type IPNetwork (line 12) | type IPNetwork
method MarshalJSON (line 15) | func (n IPNetwork) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 20) | func (n *IPNetwork) UnmarshalJSON(b []byte) error {
method String (line 46) | func (n IPNetwork) String() string {
method Contains (line 52) | func (n IPNetwork) Contains(ip net.IP) bool {
FILE: internal/conf/ip_networks.go
type IPNetworks (line 12) | type IPNetworks
method UnmarshalEnv (line 15) | func (d *IPNetworks) UnmarshalEnv(_ string, v string) error {
method ToTrustedProxies (line 21) | func (d *IPNetworks) ToTrustedProxies() []string {
method Contains (line 30) | func (d IPNetworks) Contains(ip net.IP) bool {
FILE: internal/conf/jsonwrapper/unmarshal.go
function jsonFieldKey (line 18) | func jsonFieldKey(f reflect.StructField) string {
function isJSONNull (line 26) | func isJSONNull(raw json.RawMessage) bool {
function needsCustomDecode (line 30) | func needsCustomDecode(t reflect.Type) bool {
function checkForUnknownFields (line 37) | func checkForUnknownFields(rawMap map[string]json.RawMessage, known map[...
function decode (line 49) | func decode(v reflect.Value, raw json.RawMessage, path string) error {
function Unmarshal (line 147) | func Unmarshal(buf []byte, dest any) error {
function Decode (line 152) | func Decode(r io.Reader, dest any) error {
FILE: internal/conf/jsonwrapper/unmarshal_test.go
type testStruct (line 11) | type testStruct struct
function TestUnmarshalUnknownFields (line 16) | func TestUnmarshalUnknownFields(t *testing.T) {
function TestUnmarshalPreventSliceReuse (line 24) | func TestUnmarshalPreventSliceReuse(t *testing.T) {
function TestUnmarshalSetSliceToNil (line 77) | func TestUnmarshalSetSliceToNil(t *testing.T) {
function TestUnmarshalSetNullableSliceToNil (line 111) | func TestUnmarshalSetNullableSliceToNil(t *testing.T) {
type testStructWithUnmarshaler (line 129) | type testStructWithUnmarshaler struct
method UnmarshalJSON (line 133) | func (s *testStructWithUnmarshaler) UnmarshalJSON(b []byte) error {
function TestUnmarshalStructWithCustomUnmarshalerFromString (line 143) | func TestUnmarshalStructWithCustomUnmarshalerFromString(t *testing.T) {
function FuzzUnmarshal (line 153) | func FuzzUnmarshal(f *testing.F) {
FILE: internal/conf/log_destination.go
type LogDestination (line 12) | type LogDestination
method MarshalJSON (line 15) | func (d LogDestination) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 29) | func (d *LogDestination) UnmarshalJSON(b []byte) error {
FILE: internal/conf/log_destinations.go
type LogDestinations (line 12) | type LogDestinations
method UnmarshalEnv (line 15) | func (d *LogDestinations) UnmarshalEnv(_ string, v string) error {
method ToDestinations (line 21) | func (d LogDestinations) ToDestinations() []logger.Destination {
FILE: internal/conf/log_level.go
type LogLevel (line 12) | type LogLevel
method MarshalJSON (line 15) | func (d LogLevel) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 36) | func (d *LogLevel) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 63) | func (d *LogLevel) UnmarshalEnv(_ string, v string) error {
FILE: internal/conf/optional_global.go
function newOptionalGlobalValues (line 41) | func newOptionalGlobalValues() any {
type OptionalGlobal (line 46) | type OptionalGlobal struct
method UnmarshalJSON (line 51) | func (p *OptionalGlobal) UnmarshalJSON(b []byte) error {
method MarshalJSON (line 57) | func (p *OptionalGlobal) MarshalJSON() ([]byte, error) {
FILE: internal/conf/optional_path.go
function newOptionalPathValues (line 42) | func newOptionalPathValues() any {
type OptionalPath (line 47) | type OptionalPath struct
method UnmarshalJSON (line 52) | func (p *OptionalPath) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 58) | func (p *OptionalPath) UnmarshalEnv(prefix string, _ string) error {
method MarshalJSON (line 66) | func (p *OptionalPath) MarshalJSON() ([]byte, error) {
FILE: internal/conf/path.go
function IsValidPathName (line 25) | func IsValidPathName(name string) error {
function checkSRTPassphrase (line 45) | func checkSRTPassphrase(passphrase string) error {
function checkRedirect (line 55) | func checkRedirect(v string) error {
function checkMP4MagicBytes (line 71) | func checkMP4MagicBytes(f io.ReadSeeker) error {
function checkAlwaysAvailableFile (line 96) | func checkAlwaysAvailableFile(fpath string) error {
function FindPathConf (line 130) | func FindPathConf(pathConfs map[string]*Path, name string) (*Path, []str...
type Path (line 171) | type Path struct
method setDefaults (line 308) | func (pconf *Path) setDefaults() {
method Clone (line 371) | func (pconf Path) Clone() *Path {
method validate (line 376) | func (pconf *Path) validate(
method Equal (line 865) | func (pconf *Path) Equal(other *Path) bool {
method HasStaticSource (line 870) | func (pconf Path) HasStaticSource() bool {
method HasOnDemandStaticSource (line 875) | func (pconf Path) HasOnDemandStaticSource() bool {
method HasOnDemandPublisher (line 880) | func (pconf Path) HasOnDemandPublisher() bool {
function newPath (line 363) | func newPath(defaults *Path, partial *OptionalPath) *Path {
FILE: internal/conf/path_test.go
function TestPathClone (line 10) | func TestPathClone(t *testing.T) {
FILE: internal/conf/record_format.go
type RecordFormat (line 10) | type RecordFormat
method UnmarshalJSON (line 19) | func (d *RecordFormat) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 36) | func (d *RecordFormat) UnmarshalEnv(_ string, v string) error {
constant RecordFormatFMP4 (line 14) | RecordFormatFMP4 RecordFormat = "fmp4"
constant RecordFormatMPEGTS (line 15) | RecordFormatMPEGTS RecordFormat = "mpegts"
FILE: internal/conf/rtsp_auth_method.go
type RTSPAuthMethod (line 12) | type RTSPAuthMethod
method MarshalJSON (line 15) | func (d RTSPAuthMethod) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 26) | func (d *RTSPAuthMethod) UnmarshalJSON(b []byte) error {
FILE: internal/conf/rtsp_auth_methods.go
type RTSPAuthMethods (line 12) | type RTSPAuthMethods
method UnmarshalEnv (line 15) | func (d *RTSPAuthMethods) UnmarshalEnv(_ string, v string) error {
method ToAuthMethods (line 21) | func (d RTSPAuthMethods) ToAuthMethods() []auth.VerifyMethod {
FILE: internal/conf/rtsp_range_type.go
type RTSPRangeType (line 10) | type RTSPRangeType
method UnmarshalJSON (line 21) | func (d *RTSPRangeType) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 38) | func (d *RTSPRangeType) UnmarshalEnv(_ string, v string) error {
constant RTSPRangeTypeUndefined (line 14) | RTSPRangeTypeUndefined RTSPRangeType = ""
constant RTSPRangeTypeClock (line 15) | RTSPRangeTypeClock RTSPRangeType = "clock"
constant RTSPRangeTypeNPT (line 16) | RTSPRangeTypeNPT RTSPRangeType = "npt"
constant RTSPRangeTypeSMPTE (line 17) | RTSPRangeTypeSMPTE RTSPRangeType = "smpte"
FILE: internal/conf/rtsp_transport.go
function ptrOf (line 11) | func ptrOf[T any](v T) *T {
type RTSPTransport (line 18) | type RTSPTransport struct
method MarshalJSON (line 23) | func (d RTSPTransport) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 45) | func (d *RTSPTransport) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 72) | func (d *RTSPTransport) UnmarshalEnv(_ string, v string) error {
FILE: internal/conf/rtsp_transports.go
type RTSPTransports (line 14) | type RTSPTransports
method MarshalJSON (line 17) | func (d RTSPTransports) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 45) | func (d *RTSPTransports) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 73) | func (d *RTSPTransports) UnmarshalEnv(_ string, v string) error {
FILE: internal/conf/string_size.go
type StringSize (line 9) | type StringSize
method MarshalJSON (line 12) | func (s StringSize) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 17) | func (s *StringSize) UnmarshalJSON(b []byte) error {
method UnmarshalEnv (line 33) | func (s *StringSize) UnmarshalEnv(_ string, v string) error {
FILE: internal/conf/webrtc_ice_server.go
type WebRTCICEServer (line 4) | type WebRTCICEServer struct
FILE: internal/conf/yamlwrapper/unmarshal.go
function convertLegacyBools (line 19) | func convertLegacyBools(node ast.Node) ast.Node {
function Unmarshal (line 78) | func Unmarshal(buf []byte, dest any) error {
FILE: internal/conf/yamlwrapper/unmarshal_test.go
function TestUnmarshalIntegerMapKey (line 9) | func TestUnmarshalIntegerMapKey(t *testing.T) {
function TestUnmarshalDuplicateKey (line 25) | func TestUnmarshalDuplicateKey(t *testing.T) {
function TestUnmarshalUnknownFields (line 36) | func TestUnmarshalUnknownFields(t *testing.T) {
function TestUnmarshalLegacyBools (line 52) | func TestUnmarshalLegacyBools(t *testing.T) {
function TestUnmarshalEmpty (line 67) | func TestUnmarshalEmpty(t *testing.T) {
function FuzzUnmarshal (line 75) | func FuzzUnmarshal(f *testing.F) {
FILE: internal/confwatcher/confwatcher.go
constant minInterval (line 13) | minInterval = 1 * time.Second
constant additionalWait (line 14) | additionalWait = 10 * time.Millisecond
type ConfWatcher (line 18) | type ConfWatcher struct
method Initialize (line 33) | func (w *ConfWatcher) Initialize() error {
method Close (line 64) | func (w *ConfWatcher) Close() {
method run (line 69) | func (w *ConfWatcher) run() {
method Watch (line 120) | func (w *ConfWatcher) Watch() chan struct{} {
FILE: internal/confwatcher/confwatcher_test.go
function TestNoFile (line 12) | func TestNoFile(t *testing.T) {
function TestWrite (line 18) | func TestWrite(t *testing.T) {
function TestWriteMultipleTimes (line 45) | func TestWriteMultipleTimes(t *testing.T) {
function TestDeleteCreate (line 89) | func TestDeleteCreate(t *testing.T) {
function TestSymlinkDeleteCreate (line 119) | func TestSymlinkDeleteCreate(t *testing.T) {
FILE: internal/core/api_test.go
function checkClose (line 35) | func checkClose(t *testing.T, closeFunc func() error) {
function httpRequest (line 39) | func httpRequest(t *testing.T, hc *http.Client, method string, ur string...
function checkError (line 70) | func checkError(t *testing.T, msg string, body io.Reader) {
function TestAPIPathsList (line 77) | func TestAPIPathsList(t *testing.T) {
function TestAPIPathsGet (line 286) | func TestAPIPathsGet(t *testing.T) {
function TestAPIProtocolListGet (line 355) | func TestAPIProtocolListGet(t *testing.T) {
function TestAPIProtocolGetNotFound (line 990) | func TestAPIProtocolGetNotFound(t *testing.T) {
function TestAPIProtocolKick (line 1094) | func TestAPIProtocolKick(t *testing.T) {
function TestAPIProtocolKickNotFound (line 1272) | func TestAPIProtocolKickNotFound(t *testing.T) {
FILE: internal/core/core.go
function goArm (line 58) | func goArm() string {
function getArch (line 68) | func getArch() string {
function atLeastOneRecordDeleteAfter (line 78) | func atLeastOneRecordDeleteAfter(pathConfs map[string]*conf.Path) bool {
function getRTPMaxPayloadSize (line 87) | func getRTPMaxPayloadSize(udpMaxPayloadSize int, rtspEncryption conf.Enc...
type Core (line 106) | type Core struct
method Close (line 217) | func (p *Core) Close() {
method Wait (line 223) | func (p *Core) Wait() {
method Log (line 228) | func (p *Core) Log(level logger.Level, format string, args ...any) {
method run (line 232) | func (p *Core) run() {
method createResources (line 289) | func (p *Core) createResources(initial bool) error {
method closeResources (line 725) | func (p *Core) closeResources(newConf *conf.Conf, calledByAPI bool) {
method reloadConf (line 1070) | func (p *Core) reloadConf(newConf *conf.Conf, calledByAPI bool) error {
method APIConfigSet (line 1091) | func (p *Core) APIConfigSet(conf *conf.Conf) {
function New (line 137) | func New(args []string) (*Core, bool) {
FILE: internal/core/core_test.go
function newInstance (line 15) | func newInstance(conf string) (*Core, bool) {
function TestCoreErrors (line 29) | func TestCoreErrors(t *testing.T) {
function TestCoreHotReloading (line 98) | func TestCoreHotReloading(t *testing.T) {
function TestCoreHotReloadingAndLoggerError (line 136) | func TestCoreHotReloadingAndLoggerError(t *testing.T) {
FILE: internal/core/metrics_test.go
function httpPullFile (line 31) | func httpPullFile(t *testing.T, hc *http.Client, u string) []byte {
function TestMetrics (line 46) | func TestMetrics(t *testing.T) {
FILE: internal/core/path.go
function emptyTimer (line 24) | func emptyTimer() *time.Timer {
type pathParent (line 30) | type pathParent interface
type pathOnDemandState (line 39) | type pathOnDemandState
constant pathOnDemandStateInitial (line 42) | pathOnDemandStateInitial pathOnDemandState = iota
constant pathOnDemandStateWaitingReady (line 43) | pathOnDemandStateWaitingReady
constant pathOnDemandStateReady (line 44) | pathOnDemandStateReady
constant pathOnDemandStateClosing (line 45) | pathOnDemandStateClosing
type pathAPIPathsListRes (line 48) | type pathAPIPathsListRes struct
type pathAPIPathsListReq (line 53) | type pathAPIPathsListReq struct
type pathAPIPathsGetRes (line 57) | type pathAPIPathsGetRes struct
type pathAPIPathsGetReq (line 63) | type pathAPIPathsGetReq struct
type path (line 68) | type path struct
method initialize (line 125) | func (pa *path) initialize() {
method close (line 154) | func (pa *path) close() {
method wait (line 158) | func (pa *path) wait() {
method Log (line 163) | func (pa *path) Log(level logger.Level, format string, args ...any) {
method Name (line 167) | func (pa *path) Name() string {
method isAvailable (line 171) | func (pa *path) isAvailable() bool {
method isOnline (line 175) | func (pa *path) isOnline() bool {
method run (line 179) | func (pa *path) run() {
method runInner (line 263) | func (pa *path) runInner() error {
method doOnDemandStaticSourceReadyTimer (line 349) | func (pa *path) doOnDemandStaticSourceReadyTimer() {
method doOnDemandStaticSourceCloseTimer (line 363) | func (pa *path) doOnDemandStaticSourceCloseTimer() {
method doOnDemandPublisherReadyTimer (line 371) | func (pa *path) doOnDemandPublisherReadyTimer() {
method doOnDemandPublisherCloseTimer (line 385) | func (pa *path) doOnDemandPublisherCloseTimer() {
method doReloadConf (line 389) | func (pa *path) doReloadConf(newConf *conf.Path) {
method doSourceStaticSetReady (line 416) | func (pa *path) doSourceStaticSetReady(req defs.PathSourceStaticSetRea...
method doSourceStaticSetNotReady (line 453) | func (pa *path) doSourceStaticSetNotReady(req defs.PathSourceStaticSet...
method doDescribe (line 472) | func (pa *path) doDescribe(req defs.PathDescribeReq) {
method doRemovePublisher (line 511) | func (pa *path) doRemovePublisher(req defs.PathRemovePublisherReq) {
method doAddPublisher (line 518) | func (pa *path) doAddPublisher(req defs.PathAddPublisherReq) {
method doAddReader (line 578) | func (pa *path) doAddReader(req defs.PathAddReaderReq) {
method doRemoveReader (line 603) | func (pa *path) doRemoveReader(req defs.PathRemoveReaderReq) {
method doAPIPathsGet (line 622) | func (pa *path) doAPIPathsGet(req pathAPIPathsGetReq) {
method SafeConf (line 713) | func (pa *path) SafeConf() *conf.Path {
method ExternalCmdEnv (line 719) | func (pa *path) ExternalCmdEnv() externalcmd.Environment {
method shouldClose (line 736) | func (pa *path) shouldClose() bool {
method onDemandStaticSourceStart (line 744) | func (pa *path) onDemandStaticSourceStart(query string) {
method onDemandStaticSourceScheduleClose (line 753) | func (pa *path) onDemandStaticSourceScheduleClose() {
method onDemandStaticSourceStop (line 760) | func (pa *path) onDemandStaticSourceStop(reason string) {
method onDemandPublisherStart (line 771) | func (pa *path) onDemandPublisherStart(query string) {
method onDemandPublisherScheduleClose (line 786) | func (pa *path) onDemandPublisherScheduleClose() {
method onDemandPublisherStop (line 793) | func (pa *path) onDemandPublisherStop(reason string) {
method setAvailable (line 805) | func (pa *path) setAvailable(
method consumeOnHoldRequests (line 861) | func (pa *path) consumeOnHoldRequests() {
method setNotAvailable (line 875) | func (pa *path) setNotAvailable() {
method startRecording (line 896) | func (pa *path) startRecording() {
method executeRemoveReader (line 939) | func (pa *path) executeRemoveReader(r defs.Reader) {
method executeRemovePublisher (line 943) | func (pa *path) executeRemovePublisher() {
method addReaderPost (line 955) | func (pa *path) addReaderPost(req defs.PathAddReaderReq) {
method reloadConf (line 986) | func (pa *path) reloadConf(newConf *conf.Path) {
method StaticSourceHandlerSetReady (line 994) | func (pa *path) StaticSourceHandlerSetReady(
method StaticSourceHandlerSetNotReady (line 1012) | func (pa *path) StaticSourceHandlerSetNotReady(
method describe (line 1030) | func (pa *path) describe(req defs.PathDescribeReq) defs.PathDescribeRes {
method addPublisher (line 1040) | func (pa *path) addPublisher(req defs.PathAddPublisherReq) (*defs.Path...
method RemovePublisher (line 1051) | func (pa *path) RemovePublisher(req defs.PathRemovePublisherReq) {
method addReader (line 1061) | func (pa *path) addReader(req defs.PathAddReaderReq) (*defs.PathAddRea...
method RemoveReader (line 1072) | func (pa *path) RemoveReader(req defs.PathRemoveReaderReq) {
method APIPathsGet (line 1082) | func (pa *path) APIPathsGet(req pathAPIPathsGetReq) (*defs.APIPath, er...
FILE: internal/core/path_manager.go
function pathConfCanBeUpdated (line 20) | func pathConfCanBeUpdated(oldPathConf *conf.Path, newPathConf *conf.Path...
type pathSetHLSServerRes (line 54) | type pathSetHLSServerRes struct
type pathSetHLSServerReq (line 58) | type pathSetHLSServerReq struct
type pathManagerAuthManager (line 63) | type pathManagerAuthManager interface
type pathManagerParent (line 67) | type pathManagerParent interface
type pathManager (line 71) | type pathManager struct
method initialize (line 107) | func (pm *pathManager) initialize() {
method close (line 142) | func (pm *pathManager) close() {
method Log (line 154) | func (pm *pathManager) Log(level logger.Level, format string, args ......
method run (line 158) | func (pm *pathManager) run() {
method doReloadConf (line 213) | func (pm *pathManager) doReloadConf(newPaths map[string]*conf.Path) {
method doClosePath (line 277) | func (pm *pathManager) doClosePath(pa *path) {
method doSetHLSServer (line 283) | func (pm *pathManager) doSetHLSServer(m *hls.Server) []defs.Path {
method doSetPathReady (line 297) | func (pm *pathManager) doSetPathReady(pa *path) {
method doSetPathNotReady (line 309) | func (pm *pathManager) doSetPathNotReady(pa *path) {
method doFindPathConf (line 321) | func (pm *pathManager) doFindPathConf(req defs.PathFindPathConfReq) {
method doDescribe (line 340) | func (pm *pathManager) doDescribe(req defs.PathDescribeReq) {
method doAddReader (line 365) | func (pm *pathManager) doAddReader(req defs.PathAddReaderReq) {
method doAddPublisher (line 398) | func (pm *pathManager) doAddPublisher(req defs.PathAddPublisherReq) {
method doAPIPathsList (line 436) | func (pm *pathManager) doAPIPathsList(req pathAPIPathsListReq) {
method doAPIPathsGet (line 443) | func (pm *pathManager) doAPIPathsGet(req pathAPIPathsGetReq) {
method createPath (line 453) | func (pm *pathManager) createPath(
method ReloadPathConfs (line 480) | func (pm *pathManager) ReloadPathConfs(pathConfs map[string]*conf.Path) {
method setPathReady (line 488) | func (pm *pathManager) setPathReady(pa *path) {
method setPathNotReady (line 497) | func (pm *pathManager) setPathNotReady(pa *path) {
method removePath (line 506) | func (pm *pathManager) removePath(pa *path) {
method closePathIfIdle (line 515) | func (pm *pathManager) closePathIfIdle(pa *path) {
method FindPathConf (line 524) | func (pm *pathManager) FindPathConf(req defs.PathFindPathConfReq) (*de...
method Describe (line 537) | func (pm *pathManager) Describe(req defs.PathDescribeReq) defs.PathDes...
method AddPublisher (line 560) | func (pm *pathManager) AddPublisher(req defs.PathAddPublisherReq) (*de...
method AddReader (line 585) | func (pm *pathManager) AddReader(req defs.PathAddReaderReq) (*defs.Pat...
method SetHLSServer (line 610) | func (pm *pathManager) SetHLSServer(s *hls.Server) []defs.Path {
method APIPathsList (line 627) | func (pm *pathManager) APIPathsList() (*defs.APIPathList, error) {
method APIPathsGet (line 659) | func (pm *pathManager) APIPathsGet(name string) (*defs.APIPath, error) {
FILE: internal/core/path_manager_test.go
type dummyPublisher (line 20) | type dummyPublisher struct
method Close (line 22) | func (d *dummyPublisher) Close() {}
method Log (line 24) | func (d *dummyPublisher) Log(_ logger.Level, _ string, _ ...any) {}
method APISourceDescribe (line 26) | func (d *dummyPublisher) APISourceDescribe() *defs.APIPathSource {
type dummyReader (line 30) | type dummyReader struct
method Close (line 32) | func (d *dummyReader) Close() {}
method Log (line 34) | func (d *dummyReader) Log(_ logger.Level, _ string, _ ...any) {}
method APIReaderDescribe (line 36) | func (d *dummyReader) APIReaderDescribe() *defs.APIPathReader {
function TestPathManagerDynamicPathAutoDeletion (line 40) | func TestPathManagerDynamicPathAutoDeletion(t *testing.T) {
function TestPathManagerDynamicPathDescribeAndPublish (line 88) | func TestPathManagerDynamicPathDescribeAndPublish(t *testing.T) {
function TestPathManagerConfigHotReload (line 125) | func TestPathManagerConfigHotReload(t *testing.T) {
FILE: internal/core/path_test.go
type testServer (line 32) | type testServer struct
method OnDescribe (line 38) | func (sh *testServer) OnDescribe(ctx *gortsplib.ServerHandlerOnDescrib...
method OnSetup (line 43) | func (sh *testServer) OnSetup(ctx *gortsplib.ServerHandlerOnSetupCtx) ...
method OnPlay (line 47) | func (sh *testServer) OnPlay(ctx *gortsplib.ServerHandlerOnPlayCtx) (*...
function TestPathRunOnDemand (line 53) | func TestPathRunOnDemand(t *testing.T) {
function TestPathRunOnConnect (line 154) | func TestPathRunOnConnect(t *testing.T) {
function TestPathRunOnReady (line 281) | func TestPathRunOnReady(t *testing.T) {
function TestPathRunOnRead (line 332) | func TestPathRunOnRead(t *testing.T) {
function TestPathRunOnRecordSegment (line 590) | func TestPathRunOnRecordSegment(t *testing.T) {
function TestPathMaxReaders (line 657) | func TestPathMaxReaders(t *testing.T) {
function TestPathRecord (line 702) | func TestPathRecord(t *testing.T) {
function TestPathFallback (line 785) | func TestPathFallback(t *testing.T) {
function TestPathResolveSource (line 844) | func TestPathResolveSource(t *testing.T) {
function TestPathOverridePublisher (line 908) | func TestPathOverridePublisher(t *testing.T) {
FILE: internal/core/source_redirect.go
type sourceRedirect (line 9) | type sourceRedirect struct
method Log (line 11) | func (*sourceRedirect) Log(logger.Level, string, ...any) {
method APISourceDescribe (line 15) | func (*sourceRedirect) APISourceDescribe() *defs.APIPathSource {
FILE: internal/core/test_on_demand/main.go
function main (line 14) | func main() {
FILE: internal/core/upgrade.go
constant gitRepo (line 25) | gitRepo = "https://github.com/bluenviron/mediamtx"
constant downloadURL (line 26) | downloadURL = "https://github.com/bluenviron/mediamtx/releases/download/...
constant executable (line 27) | executable = "mediamtx"
function latestRemoteVersion (line 35) | func latestRemoteVersion() (*semver.Version, error) {
function extractExecutable (line 64) | func extractExecutable(r io.Reader) ([]byte, error) {
function extractExecutableWin (line 92) | func extractExecutableWin(r io.Reader) ([]byte, error) {
function upgrade (line 123) | func upgrade() error {
FILE: internal/core/upgrade_disabled.go
function upgrade (line 7) | func upgrade() error {
FILE: internal/core/versiongetter/main.go
function gitDescribeTags (line 21) | func gitDescribeTags(repo *git.Repository) (string, error) {
function tagFromGit (line 75) | func tagFromGit() error {
function do (line 122) | func do() error {
function main (line 137) | func main() {
FILE: internal/counterdumper/dumper.go
constant callbackPeriod (line 10) | callbackPeriod = 1 * time.Second
type Dumper (line 14) | type Dumper struct
method Start (line 26) | func (c *Dumper) Start() {
method Stop (line 34) | func (c *Dumper) Stop() {
method Increase (line 40) | func (c *Dumper) Increase() {
method Add (line 48) | func (c *Dumper) Add(v uint64) {
method Get (line 56) | func (c *Dumper) Get() uint64 {
method run (line 62) | func (c *Dumper) run() {
FILE: internal/counterdumper/dumper_test.go
function TestDumperReport (line 10) | func TestDumperReport(t *testing.T) {
function TestDumperDoNotReport (line 32) | func TestDumperDoNotReport(t *testing.T) {
FILE: internal/defs/api.go
type APIOKStatus (line 10) | type APIOKStatus
constant APIOKStatusOK (line 14) | APIOKStatusOK APIOKStatus = "ok"
type APIErrorStatus (line 18) | type APIErrorStatus
constant APIErrorStatusError (line 22) | APIErrorStatusError APIErrorStatus = "error"
type APIOK (line 26) | type APIOK struct
type APIError (line 31) | type APIError struct
type APIInfo (line 37) | type APIInfo struct
type APIPathConfList (line 43) | type APIPathConfList struct
FILE: internal/defs/api_hls.go
type APIHLSServer (line 6) | type APIHLSServer interface
type APIHLSMuxer (line 12) | type APIHLSMuxer struct
type APIHLSMuxerList (line 23) | type APIHLSMuxerList struct
FILE: internal/defs/api_path.go
type APIPathManager (line 8) | type APIPathManager interface
type APIPathSourceType (line 14) | type APIPathSourceType
constant APIPathSourceTypeHLSSource (line 18) | APIPathSourceTypeHLSSource APIPathSourceType = "hlsSource"
constant APIPathSourceTypeRedirect (line 19) | APIPathSourceTypeRedirect APIPathSourceType = "redirect"
constant APIPathSourceTypeRPICameraSource (line 20) | APIPathSourceTypeRPICameraSource APIPathSourceType = "rpiCameraSource"
constant APIPathSourceTypeRTMPConn (line 21) | APIPathSourceTypeRTMPConn APIPathSourceType = "rtmpConn"
constant APIPathSourceTypeRTMPSConn (line 22) | APIPathSourceTypeRTMPSConn APIPathSourceType = "rtmpsConn"
constant APIPathSourceTypeRTMPSource (line 23) | APIPathSourceTypeRTMPSource APIPathSourceType = "rtmpSource"
constant APIPathSourceTypeRTSPSession (line 24) | APIPathSourceTypeRTSPSession APIPathSourceType = "rtspSession"
constant APIPathSourceTypeRTSPSource (line 25) | APIPathSourceTypeRTSPSource APIPathSourceType = "rtspSource"
constant APIPathSourceTypeRTSPSSession (line 26) | APIPathSourceTypeRTSPSSession APIPathSourceType = "rtspsSession"
constant APIPathSourceTypeSRTConn (line 27) | APIPathSourceTypeSRTConn APIPathSourceType = "srtConn"
constant APIPathSourceTypeSRTSource (line 28) | APIPathSourceTypeSRTSource APIPathSourceType = "srtSource"
constant APIPathSourceTypeMPEGTSSource (line 29) | APIPathSourceTypeMPEGTSSource APIPathSourceType = "mpegtsSource"
constant APIPathSourceTypeRTPSource (line 30) | APIPathSourceTypeRTPSource APIPathSourceType = "rtpSource"
constant APIPathSourceTypeWebRTCSession (line 31) | APIPathSourceTypeWebRTCSession APIPathSourceType = "webRTCSession"
constant APIPathSourceTypeWebRTCSource (line 32) | APIPathSourceTypeWebRTCSource APIPathSourceType = "webRTCSource"
type APIPathSource (line 36) | type APIPathSource struct
type APIPathReaderType (line 42) | type APIPathReaderType
constant APIPathReaderTypeHLSMuxer (line 46) | APIPathReaderTypeHLSMuxer APIPathReaderType = "hlsMuxer"
constant APIPathReaderTypeRTMPConn (line 47) | APIPathReaderTypeRTMPConn APIPathReaderType = "rtmpConn"
constant APIPathReaderTypeRTMPSConn (line 48) | APIPathReaderTypeRTMPSConn APIPathReaderType = "rtmpsConn"
constant APIPathReaderTypeRTSPConn (line 49) | APIPathReaderTypeRTSPConn APIPathReaderType = "rtspConn"
constant APIPathReaderTypeRPICameraSecondary (line 50) | APIPathReaderTypeRPICameraSecondary APIPathReaderType = "rpiCameraSecond...
constant APIPathReaderTypeRTSPSession (line 51) | APIPathReaderTypeRTSPSession APIPathReaderType = "rtspSession"
constant APIPathReaderTypeRTSPSConn (line 52) | APIPathReaderTypeRTSPSConn APIPathReaderType = "rtspsConn"
constant APIPathReaderTypeRTSPSSession (line 53) | APIPathReaderTypeRTSPSSession APIPathReaderType = "rtspsSession"
constant APIPathReaderTypeSRTConn (line 54) | APIPathReaderTypeSRTConn APIPathReaderType = "srtConn"
constant APIPathReaderTypeWebRTCSession (line 55) | APIPathReaderTypeWebRTCSession APIPathReaderType = "webRTCSession"
type APIPathReader (line 59) | type APIPathReader struct
type APIPath (line 65) | type APIPath struct
type APIPathList (line 87) | type APIPathList struct
FILE: internal/defs/api_path_track.go
type APIPathTrack (line 4) | type APIPathTrack struct
FILE: internal/defs/api_path_track_codec.go
type APIPathTrackCodec (line 14) | type APIPathTrackCodec
constant APIPathTrackCodecAV1 (line 19) | APIPathTrackCodecAV1 APIPathTrackCodec = "AV1"
constant APIPathTrackCodecVP9 (line 20) | APIPathTrackCodecVP9 APIPathTrackCodec = "VP9"
constant APIPathTrackCodecVP8 (line 21) | APIPathTrackCodecVP8 APIPathTrackCodec = "VP8"
constant APIPathTrackCodecH265 (line 22) | APIPathTrackCodecH265 APIPathTrackCodec = "H265"
constant APIPathTrackCodecH264 (line 23) | APIPathTrackCodecH264 APIPathTrackCodec = "H264"
constant APIPathTrackCodecMPEG4Video (line 24) | APIPathTrackCodecMPEG4Video APIPathTrackCodec = "MPEG-4 Video"
constant APIPathTrackCodecMPEG1Video (line 25) | APIPathTrackCodecMPEG1Video APIPathTrackCodec = "MPEG-1 Video"
constant APIPathTrackCodecMJPEG (line 26) | APIPathTrackCodecMJPEG APIPathTrackCodec = "MJPEG"
constant APIPathTrackCodecOpus (line 28) | APIPathTrackCodecOpus APIPathTrackCodec = "Opus"
constant APIPathTrackCodecVorbis (line 29) | APIPathTrackCodecVorbis APIPathTrackCodec = "Vorbis"
constant APIPathTrackCodecMPEG4Audio (line 30) | APIPathTrackCodecMPEG4Audio APIPathTrackCodec = "MPEG-4 Audio"
constant APIPathTrackCodecMPEG4AudioLATM (line 31) | APIPathTrackCodecMPEG4AudioLATM APIPathTrackCodec = "MPEG-4 Audio LATM"
constant APIPathTrackCodecMPEG1Audio (line 32) | APIPathTrackCodecMPEG1Audio APIPathTrackCodec = "MPEG-1 Audio"
constant APIPathTrackCodecAC3 (line 33) | APIPathTrackCodecAC3 APIPathTrackCodec = "AC3"
constant APIPathTrackCodecSpeex (line 34) | APIPathTrackCodecSpeex APIPathTrackCodec = "Speex"
constant APIPathTrackCodecG726 (line 35) | APIPathTrackCodecG726 APIPathTrackCodec = "G726"
constant APIPathTrackCodecG722 (line 36) | APIPathTrackCodecG722 APIPathTrackCodec = "G722"
constant APIPathTrackCodecG711 (line 37) | APIPathTrackCodecG711 APIPathTrackCodec = "G711"
constant APIPathTrackCodecLPCM (line 38) | APIPathTrackCodecLPCM APIPathTrackCodec = "LPCM"
constant APIPathTrackCodecMPEGTS (line 40) | APIPathTrackCodecMPEGTS APIPathTrackCodec = "MPEG-TS"
constant APIPathTrackCodecKLV (line 41) | APIPathTrackCodecKLV APIPathTrackCodec = "KLV"
constant APIPathTrackCodecGeneric (line 42) | APIPathTrackCodecGeneric APIPathTrackCodec = "Generic"
function formatToCodec (line 45) | func formatToCodec(forma format.Format) APIPathTrackCodec {
function h264ProfileString (line 97) | func h264ProfileString(profileIdc uint8) string {
function h264LevelString (line 118) | func h264LevelString(levelIdc uint8) string {
function h265ProfileString (line 127) | func h265ProfileString(profileIdc uint8) string {
function h265LevelString (line 154) | func h265LevelString(levelIdc uint8) string {
function FormatsToCodecs (line 165) | func FormatsToCodecs(formats []format.Format) []APIPathTrackCodec {
function formatToTrack (line 173) | func formatToTrack(forma format.Format) APIPathTrack {
function formatToTrackCodecProps (line 180) | func formatToTrackCodecProps(forma format.Format) APIPathTrackCodecProps {
function gatherFormats (line 278) | func gatherFormats(medias []*description.Media) []format.Format {
function MediasToCodecs (line 299) | func MediasToCodecs(medias []*description.Media) []APIPathTrackCodec {
function FormatsToTracks (line 304) | func FormatsToTracks(formats []format.Format) []APIPathTrack {
function MediasToTracks (line 315) | func MediasToTracks(medias []*description.Media) []APIPathTrack {
FILE: internal/defs/api_path_track_codec_props.go
type APIPathTrackCodecProps (line 4) | type APIPathTrackCodecProps interface
type APIPathTrackCodecPropsAV1 (line 9) | type APIPathTrackCodecPropsAV1 struct
method apiPathTrackCodecProps (line 17) | func (*APIPathTrackCodecPropsAV1) apiPathTrackCodecProps() {}
type APIPathTrackCodecPropsVP9 (line 20) | type APIPathTrackCodecPropsVP9 struct
method apiPathTrackCodecProps (line 24) | func (*APIPathTrackCodecPropsVP9) apiPathTrackCodecProps() {}
type APIPathTrackCodecPropsH265 (line 27) | type APIPathTrackCodecPropsH265 struct
method apiPathTrackCodecProps (line 34) | func (*APIPathTrackCodecPropsH265) apiPathTrackCodecProps() {}
type APIPathTrackCodecPropsH264 (line 37) | type APIPathTrackCodecPropsH264 struct
method apiPathTrackCodecProps (line 44) | func (*APIPathTrackCodecPropsH264) apiPathTrackCodecProps() {}
type APIPathTrackCodecPropsOpus (line 47) | type APIPathTrackCodecPropsOpus struct
method apiPathTrackCodecProps (line 51) | func (*APIPathTrackCodecPropsOpus) apiPathTrackCodecProps() {}
type APIPathTrackCodecPropsMPEG4Audio (line 54) | type APIPathTrackCodecPropsMPEG4Audio struct
method apiPathTrackCodecProps (line 59) | func (*APIPathTrackCodecPropsMPEG4Audio) apiPathTrackCodecProps() {}
type APIPathTrackCodecPropsAC3 (line 62) | type APIPathTrackCodecPropsAC3 struct
method apiPathTrackCodecProps (line 67) | func (*APIPathTrackCodecPropsAC3) apiPathTrackCodecProps() {}
type APIPathTrackCodecPropsG711 (line 70) | type APIPathTrackCodecPropsG711 struct
method apiPathTrackCodecProps (line 76) | func (*APIPathTrackCodecPropsG711) apiPathTrackCodecProps() {}
type APIPathTrackCodecPropsLPCM (line 79) | type APIPathTrackCodecPropsLPCM struct
method apiPathTrackCodecProps (line 85) | func (*APIPathTrackCodecPropsLPCM) apiPathTrackCodecProps() {}
FILE: internal/defs/api_path_track_codec_test.go
function ptr (line 12) | func ptr[T any](v T) *T {
function testFormatH264 (line 16) | func testFormatH264() *format.H264 {
function testFormatMPEG4Audio (line 29) | func testFormatMPEG4Audio() *format.MPEG4Audio {
function testFormatH265 (line 44) | func testFormatH265() *format.H265 {
function TestFormatsToCodecs (line 68) | func TestFormatsToCodecs(t *testing.T) {
function TestMediasToTracks (line 120) | func TestMediasToTracks(t *testing.T) {
FILE: internal/defs/api_recording.go
type APIRecordingSegment (line 6) | type APIRecordingSegment struct
type APIRecording (line 11) | type APIRecording struct
type APIRecordingList (line 17) | type APIRecordingList struct
FILE: internal/defs/api_rtmp.go
type APIRTMPServer (line 10) | type APIRTMPServer interface
type APIRTMPConnState (line 17) | type APIRTMPConnState
constant APIRTMPConnStateIdle (line 21) | APIRTMPConnStateIdle APIRTMPConnState = "idle"
constant APIRTMPConnStateRead (line 22) | APIRTMPConnStateRead APIRTMPConnState = "read"
constant APIRTMPConnStatePublish (line 23) | APIRTMPConnStatePublish APIRTMPConnState = "publish"
type APIRTMPConn (line 27) | type APIRTMPConn struct
type APIRTMPConnList (line 44) | type APIRTMPConnList struct
FILE: internal/defs/api_rtsp.go
type APIRTSPServer (line 10) | type APIRTSPServer interface
type APIRTSPConn (line 19) | type APIRTSPConn struct
type APIRTSPConnsList (line 32) | type APIRTSPConnsList struct
type APIRTSPSessionState (line 39) | type APIRTSPSessionState
constant APIRTSPSessionStateIdle (line 43) | APIRTSPSessionStateIdle APIRTSPSessionState = "idle"
constant APIRTSPSessionStateRead (line 44) | APIRTSPSessionStateRead APIRTSPSessionState = "read"
constant APIRTSPSessionStatePublish (line 45) | APIRTSPSessionStatePublish APIRTSPSessionState = "publish"
type APIRTSPSession (line 49) | type APIRTSPSession struct
type APIRTSPSessionList (line 86) | type APIRTSPSessionList struct
FILE: internal/defs/api_srt.go
type APISRTServer (line 10) | type APISRTServer interface
type APISRTConnState (line 17) | type APISRTConnState
constant APISRTConnStateIdle (line 21) | APISRTConnStateIdle APISRTConnState = "idle"
constant APISRTConnStateRead (line 22) | APISRTConnStateRead APISRTConnState = "read"
constant APISRTConnStatePublish (line 23) | APISRTConnStatePublish APISRTConnState = "publish"
type APISRTConn (line 27) | type APISRTConn struct
type APISRTConnList (line 161) | type APISRTConnList struct
FILE: internal/defs/api_webrtc.go
type APIWebRTCServer (line 10) | type APIWebRTCServer interface
type APIWebRTCSessionState (line 17) | type APIWebRTCSessionState
constant APIWebRTCSessionStateRead (line 21) | APIWebRTCSessionStateRead APIWebRTCSessionState = "read"
constant APIWebRTCSessionStatePublish (line 22) | APIWebRTCSessionStatePublish APIWebRTCSessionState = "publish"
type APIWebRTCSession (line 26) | type APIWebRTCSession struct
type APIWebRTCSessionList (line 58) | type APIWebRTCSessionList struct
FILE: internal/defs/path.go
type PathNoStreamAvailableError (line 14) | type PathNoStreamAvailableError struct
method Error (line 19) | func (e PathNoStreamAvailableError) Error() string {
type Path (line 24) | type Path interface
type PathFindPathConfRes (line 33) | type PathFindPathConfRes struct
type PathFindPathConfReq (line 40) | type PathFindPathConfReq struct
type PathDescribeRes (line 46) | type PathDescribeRes struct
type PathDescribeReq (line 54) | type PathDescribeReq struct
type PathAddPublisherRes (line 60) | type PathAddPublisherRes struct
type PathAddPublisherReq (line 68) | type PathAddPublisherReq struct
type PathRemovePublisherReq (line 79) | type PathRemovePublisherReq struct
type PathAddReaderRes (line 85) | type PathAddReaderRes struct
type PathAddReaderReq (line 93) | type PathAddReaderReq struct
type PathRemoveReaderReq (line 100) | type PathRemoveReaderReq struct
type PathSourceStaticSetReadyRes (line 106) | type PathSourceStaticSetReadyRes struct
type PathSourceStaticSetReadyReq (line 112) | type PathSourceStaticSetReadyReq struct
type PathSourceStaticSetNotReadyReq (line 120) | type PathSourceStaticSetNotReadyReq struct
FILE: internal/defs/path_access_request.go
type PathAccessRequest (line 12) | type PathAccessRequest struct
method ToAuthRequest (line 27) | func (r *PathAccessRequest) ToAuthRequest() *auth.Request {
FILE: internal/defs/publisher.go
type Publisher (line 4) | type Publisher interface
FILE: internal/defs/reader.go
type Reader (line 4) | type Reader interface
FILE: internal/defs/source.go
type Source (line 18) | type Source interface
function FormatsInfo (line 24) | func FormatsInfo(formats []format.Format) string {
function MediasInfo (line 43) | func MediasInfo(medias []*description.Media) string {
FILE: internal/defs/static_source.go
type StaticSourceRunParams (line 10) | type StaticSourceRunParams struct
FILE: internal/errordumper/dumper.go
constant callbackPeriod (line 10) | callbackPeriod = 1 * time.Second
type Dumper (line 14) | type Dumper struct
method Start (line 27) | func (c *Dumper) Start() {
method Stop (line 35) | func (c *Dumper) Stop() {
method Add (line 41) | func (c *Dumper) Add(err error) {
method Get (line 50) | func (c *Dumper) Get() uint64 {
method run (line 56) | func (c *Dumper) run() {
FILE: internal/errordumper/dumper_test.go
function TestDumperReport (line 11) | func TestDumperReport(t *testing.T) {
function TestDumperDoNotReport (line 33) | func TestDumperDoNotReport(t *testing.T) {
FILE: internal/externalcmd/cmd.go
constant restartPause (line 12) | restartPause = 5 * time.Second
type OnExitFunc (line 18) | type OnExitFunc
type Environment (line 21) | type Environment
type Cmd (line 24) | type Cmd struct
method Close (line 73) | func (e *Cmd) Close() {
method run (line 77) | func (e *Cmd) run() {
function NewCmd (line 36) | func NewCmd(
FILE: internal/externalcmd/cmd_unix.go
method runOSSpecific (line 15) | func (e *Cmd) runOSSpecific(env []string) error {
FILE: internal/externalcmd/cmd_win.go
function createProcessGroup (line 19) | func createProcessGroup() (windows.Handle, error) {
function closeProcessGroup (line 42) | func closeProcessGroup(h windows.Handle) error {
function addProcessToGroup (line 46) | func addProcessToGroup(h windows.Handle, p *os.Process) error {
method runOSSpecific (line 64) | func (e *Cmd) runOSSpecific(env []string) error {
FILE: internal/externalcmd/pool.go
type Pool (line 8) | type Pool struct
method Initialize (line 13) | func (p *Pool) Initialize() {
method Close (line 17) | func (p *Pool) Close() {
FILE: internal/hooks/on_connect.go
type OnConnectParams (line 12) | type OnConnectParams struct
function OnConnect (line 23) | func OnConnect(params OnConnectParams) func() {
FILE: internal/hooks/on_demand.go
type OnDemandParams (line 10) | type OnDemandParams struct
function OnDemand (line 19) | func OnDemand(params OnDemandParams) func(string) {
FILE: internal/hooks/on_init.go
type OnInitParams (line 10) | type OnInitParams struct
function OnInit (line 18) | func OnInit(params OnInitParams) func() {
FILE: internal/hooks/on_read.go
type OnReadParams (line 11) | type OnReadParams struct
function OnRead (line 21) | func OnRead(params OnReadParams) func() {
FILE: internal/hooks/on_ready.go
type OnReadyParams (line 11) | type OnReadyParams struct
function OnReady (line 21) | func OnReady(params OnReadyParams) func() {
FILE: internal/linters/conf/conf_test.go
function checkBooleans (line 16) | func checkBooleans(t *testing.T, keys []string, node ast.Node) {
function TestConf (line 33) | func TestConf(t *testing.T) {
FILE: internal/linters/go2api/go2api_test.go
type openAPIProperty (line 19) | type openAPIProperty struct
function wrapRef (line 30) | func wrapRef(rt reflect.Type, p openAPIProperty) openAPIProperty {
type openAPISchema (line 46) | type openAPISchema struct
type openAPI (line 52) | type openAPI struct
function schemaName (line 58) | func schemaName(rt reflect.Type) string {
function goStructToApi (line 68) | func goStructToApi(t *testing.T, rt reflect.Type) openAPIProperty {
function goEnumToApi (line 144) | func goEnumToApi(rt reflect.Type) (openAPISchema, bool) {
function TestGo2API (line 313) | func TestGo2API(t *testing.T) {
FILE: internal/logger/destination.go
type Destination (line 8) | type Destination
constant DestinationStdout (line 12) | DestinationStdout Destination = iota
constant DestinationFile (line 15) | DestinationFile
constant DestinationSyslog (line 18) | DestinationSyslog
type destination (line 21) | type destination interface
FILE: internal/logger/destination_file.go
type destinationFile (line 11) | type destinationFile struct
method log (line 29) | func (d *destinationFile) log(t time.Time, level Level, format string,...
method close (line 52) | func (d *destinationFile) close() {
function newDestinationFile (line 17) | func newDestinationFile(structured bool, filePath string) (destination, ...
FILE: internal/logger/destination_stdout.go
type destinationStdout (line 14) | type destinationStdout struct
method log (line 29) | func (d *destinationStdout) log(t time.Time, level Level, format strin...
method close (line 52) | func (d *destinationStdout) close() {
function newDestionationStdout (line 21) | func newDestionationStdout(structured bool, stdout io.Writer) destination {
FILE: internal/logger/destination_syslog.go
type destinationSysLog (line 12) | type destinationSysLog struct
method log (line 28) | func (d *destinationSysLog) log(_ time.Time, level Level, format strin...
method close (line 45) | func (d *destinationSysLog) close() {
function newDestinationSyslog (line 17) | func newDestinationSyslog(prefix string) (destination, error) {
FILE: internal/logger/destination_syslog_disabled.go
function newDestinationSyslog (line 7) | func newDestinationSyslog(_ string) (destination, error) {
FILE: internal/logger/level.go
type Level (line 4) | type Level
constant Debug (line 8) | Debug Level = iota + 1
constant Info (line 9) | Info
constant Warn (line 10) | Warn
constant Error (line 11) | Error
FILE: internal/logger/logger.go
type Logger (line 15) | type Logger struct
method Initialize (line 29) | func (l *Logger) Initialize() error {
method Close (line 64) | func (l *Logger) Close() {
method Log (line 148) | func (l *Logger) Log(level Level, format string, args ...any) {
function itoa (line 71) | func itoa(i int, wid int) []byte {
function writePlainTime (line 87) | func writePlainTime(buf *bytes.Buffer, t time.Time, useColor bool) {
function writeLevel (line 115) | func writeLevel(buf *bytes.Buffer, level Level, useColor bool) {
FILE: internal/logger/logger_test.go
function TestLoggerToStdout (line 12) | func TestLoggerToStdout(t *testing.T) {
function TestLoggerToFile (line 42) | func TestLoggerToFile(t *testing.T) {
FILE: internal/logger/writer.go
type Writer (line 4) | type Writer interface
FILE: internal/metrics/metrics.go
function interfaceIsEmpty (line 23) | func interfaceIsEmpty(i any) bool {
function sortedKeys (line 27) | func sortedKeys(paths map[string]string) []string {
function tags (line 38) | func tags(m map[string]string) string {
function metric (line 55) | func metric(key string, tags string, value int64) string {
function metricFloat (line 59) | func metricFloat(key string, tags string, value float64) string {
type metricsAuthManager (line 63) | type metricsAuthManager interface
type metricsParent (line 67) | type metricsParent interface
type Metrics (line 72) | type Metrics struct
method Initialize (line 98) | func (m *Metrics) Initialize() error {
method Close (line 131) | func (m *Metrics) Close() {
method Log (line 137) | func (m *Metrics) Log(level logger.Level, format string, args ...any) {
method middlewarePreflightRequests (line 141) | func (m *Metrics) middlewarePreflightRequests(ctx *gin.Context) {
method middlewareAuth (line 151) | func (m *Metrics) middlewareAuth(ctx *gin.Context) {
method onMetrics (line 183) | func (m *Metrics) onMetrics(ctx *gin.Context) {
method SetPathManager (line 725) | func (m *Metrics) SetPathManager(s defs.APIPathManager) {
method SetHLSServer (line 732) | func (m *Metrics) SetHLSServer(s defs.APIHLSServer) {
method SetRTSPServer (line 739) | func (m *Metrics) SetRTSPServer(s defs.APIRTSPServer) {
method SetRTSPSServer (line 746) | func (m *Metrics) SetRTSPSServer(s defs.APIRTSPServer) {
method SetRTMPServer (line 753) | func (m *Metrics) SetRTMPServer(s defs.APIRTMPServer) {
method SetRTMPSServer (line 760) | func (m *Metrics) SetRTMPSServer(s defs.APIRTMPServer) {
method SetSRTServer (line 767) | func (m *Metrics) SetSRTServer(s defs.APISRTServer) {
method SetWebRTCServer (line 774) | func (m *Metrics) SetWebRTCServer(s defs.APIWebRTCServer) {
FILE: internal/metrics/metrics_test.go
function ptrOf (line 20) | func ptrOf[T any](v T) *T {
function requireMetricsLines (line 26) | func requireMetricsLines(t *testing.T, body []byte, lines []string) {
type dummyPathManager (line 38) | type dummyPathManager struct
method APIPathsList (line 40) | func (dummyPathManager) APIPathsList() (*defs.APIPathList, error) {
method APIPathsGet (line 69) | func (dummyPathManager) APIPathsGet(string) (*defs.APIPath, error) {
type dummyHLSServer (line 73) | type dummyHLSServer struct
method APIMuxersList (line 75) | func (dummyHLSServer) APIMuxersList() (*defs.APIHLSMuxerList, error) {
method APIMuxersGet (line 90) | func (dummyHLSServer) APIMuxersGet(string) (*defs.APIHLSMuxer, error) {
type dummyRTSPServer (line 94) | type dummyRTSPServer struct
method APIConnsList (line 96) | func (dummyRTSPServer) APIConnsList() (*defs.APIRTSPConnsList, error) {
method APIConnsGet (line 113) | func (dummyRTSPServer) APIConnsGet(uuid.UUID) (*defs.APIRTSPConn, erro...
method APISessionsList (line 117) | func (dummyRTSPServer) APISessionsList() (*defs.APIRTSPSessionList, er...
method APISessionsGet (line 155) | func (dummyRTSPServer) APISessionsGet(uuid.UUID) (*defs.APIRTSPSession...
method APISessionsKick (line 159) | func (dummyRTSPServer) APISessionsKick(uuid.UUID) error {
type dummyRTMPServer (line 163) | type dummyRTMPServer struct
method APIConnsList (line 165) | func (dummyRTMPServer) APIConnsList() (*defs.APIRTMPConnList, error) {
method APIConnsGet (line 185) | func (dummyRTMPServer) APIConnsGet(uuid.UUID) (*defs.APIRTMPConn, erro...
method APIConnsKick (line 189) | func (dummyRTMPServer) APIConnsKick(uuid.UUID) error {
type dummyWebRTCServer (line 193) | type dummyWebRTCServer struct
method APISessionsList (line 195) | func (dummyWebRTCServer) APISessionsList() (*defs.APIWebRTCSessionList...
method APISessionsGet (line 230) | func (dummyWebRTCServer) APISessionsGet(uuid.UUID) (*defs.APIWebRTCSes...
method APISessionsKick (line 234) | func (dummyWebRTCServer) APISessionsKick(uuid.UUID) error {
function TestPreflightRequest (line 238) | func TestPreflightRequest(t *testing.T) {
function TestMetrics (line 276) | func TestMetrics(t *testing.T) {
function TestAuthError (line 353) | func TestAuthError(t *testing.T) {
function TestFilter (line 402) | func TestFilter(t *testing.T) {
FILE: internal/ntpestimator/estimator.go
constant maxTimeDifference (line 9) | maxTimeDifference = 5 * time.Second
function multiplyAndDivide (line 14) | func multiplyAndDivide(v, m, d time.Duration) time.Duration {
type Estimator (line 21) | type Estimator struct
method Estimate (line 31) | func (e *Estimator) Estimate(pts int64) time.Time {
FILE: internal/ntpestimator/estimator_test.go
function TestEstimator (line 10) | func TestEstimator(t *testing.T) {
FILE: internal/packetdumper/conn.go
type direction (line 19) | type direction
constant dirRead (line 22) | dirRead direction = iota
constant dirWrite (line 23) | dirWrite
constant dirHandshake (line 24) | dirHandshake
type dumpEntry (line 27) | type dumpEntry struct
type Conn (line 34) | type Conn struct
method Initialize (line 49) | func (c *Conn) Initialize() error {
method Close (line 74) | func (c *Conn) Close() error {
method run (line 82) | func (c *Conn) run() {
method processEntry (line 112) | func (c *Conn) processEntry(
method writePacket (line 164) | func (c *Conn) writePacket(
method enqueue (line 210) | func (c *Conn) enqueue(e dumpEntry) {
method Read (line 217) | func (c *Conn) Read(p []byte) (n int, err error) {
method Write (line 231) | func (c *Conn) Write(p []byte) (n int, err error) {
method LocalAddr (line 246) | func (c *Conn) LocalAddr() net.Addr { return c.Conn.LocalAddr() }
method RemoteAddr (line 249) | func (c *Conn) RemoteAddr() net.Addr { return c.Conn.RemoteAddr() }
method SetDeadline (line 252) | func (c *Conn) SetDeadline(t time.Time) error { return c.Conn.SetDeadl...
method SetReadDeadline (line 255) | func (c *Conn) SetReadDeadline(t time.Time) error { return c.Conn.SetR...
method SetWriteDeadline (line 258) | func (c *Conn) SetWriteDeadline(t time.Time) error { return c.Conn.Set...
FILE: internal/packetdumper/conn_test.go
function startTCPPair (line 15) | func startTCPPair(t *testing.T) (client, server net.Conn) {
function cleanupPcapng (line 43) | func cleanupPcapng(t *testing.T, prefix string) {
function TestConnInitialize_CreatesFile (line 55) | func TestConnInitialize_CreatesFile(t *testing.T) {
function TestConnWrite (line 67) | func TestConnWrite(t *testing.T) {
function TestConnRead (line 88) | func TestConnRead(t *testing.T) {
function TestConnServerSide (line 108) | func TestConnServerSide(t *testing.T) {
function TestConnMultipleWriteRead (line 129) | func TestConnMultipleWriteRead(t *testing.T) {
function TestConnCloseIdempotent (line 162) | func TestConnCloseIdempotent(t *testing.T) {
function TestConnDelegatesAddrMethods (line 176) | func TestConnDelegatesAddrMethods(t *testing.T) {
FILE: internal/packetdumper/dial_context.go
type DialContext (line 9) | type DialContext struct
method Do (line 15) | func (d *DialContext) Do(ctx context.Context, network, address string)...
FILE: internal/packetdumper/listen.go
type Listen (line 8) | type Listen struct
method Do (line 14) | func (l *Listen) Do(network, address string) (net.Listener, error) {
FILE: internal/packetdumper/listen_packet.go
type ListenPacket (line 8) | type ListenPacket struct
method Do (line 14) | func (l *ListenPacket) Do(network, address string) (net.PacketConn, er...
FILE: internal/packetdumper/listener.go
type Listener (line 8) | type Listener struct
method Accept (line 14) | func (l *Listener) Accept() (net.Conn, error) {
method Close (line 35) | func (l *Listener) Close() error {
method Addr (line 40) | func (l *Listener) Addr() net.Addr {
FILE: internal/packetdumper/packet_conn.go
type extendedPacketConn (line 19) | type extendedPacketConn interface
type packetDumpEntry (line 25) | type packetDumpEntry struct
type PacketConn (line 32) | type PacketConn struct
method Initialize (line 46) | func (c *PacketConn) Initialize() error {
method Close (line 69) | func (c *PacketConn) Close() error {
method run (line 77) | func (c *PacketConn) run() {
method writePacket (line 100) | func (c *PacketConn) writePacket(ntp time.Time, src, dst *net.UDPAddr,...
method enqueue (line 133) | func (c *PacketConn) enqueue(e packetDumpEntry) {
method ReadFrom (line 141) | func (c *PacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err err...
method WriteTo (line 160) | func (c *PacketConn) WriteTo(p []byte, addr net.Addr) (n int, err erro...
method LocalAddr (line 179) | func (c *PacketConn) LocalAddr() net.Addr { return c.PacketConn.LocalA...
method SetDeadline (line 182) | func (c *PacketConn) SetDeadline(t time.Time) error { return c.PacketC...
method SetReadDeadline (line 185) | func (c *PacketConn) SetReadDeadline(t time.Time) error { return c.Pac...
method SetWriteDeadline (line 188) | func (c *PacketConn) SetWriteDeadline(t time.Time) error { return c.Pa...
method SetReadBuffer (line 191) | func (c *PacketConn) SetReadBuffer(bytes int) error {
method SyscallConn (line 196) | func (c *PacketConn) SyscallConn() (syscall.RawConn, error) {
FILE: internal/packetdumper/packet_conn_test.go
function startUDPPair (line 14) | func startUDPPair(t *testing.T) (client, server *net.UDPConn) {
function cleanupPcapngPacket (line 37) | func cleanupPcapngPacket(t *testing.T, prefix string) {
function TestPacketConnInitialize_CreatesFile (line 49) | func TestPacketConnInitialize_CreatesFile(t *testing.T) {
function TestPacketConnWriteTo (line 61) | func TestPacketConnWriteTo(t *testing.T) {
function TestPacketConnReadFrom (line 83) | func TestPacketConnReadFrom(t *testing.T) {
function TestPacketConnMultipleWriteRead (line 105) | func TestPacketConnMultipleWriteRead(t *testing.T) {
function TestPacketConnCloseIdempotent (line 148) | func TestPacketConnCloseIdempotent(t *testing.T) {
function TestPacketConnDelegatesAddrMethods (line 162) | func TestPacketConnDelegatesAddrMethods(t *testing.T) {
function TestPacketConnReadFromRecordsSource (line 180) | func TestPacketConnReadFromRecordsSource(t *testing.T) {
FILE: internal/playback/muxer.go
type muxer (line 5) | type muxer interface
FILE: internal/playback/muxer_fmp4.go
constant partDuration (line 13) | partDuration = 1 * time.Second
type muxerFMP4Track (line 16) | type muxerFMP4Track struct
function findTrack (line 24) | func findTrack(tracks []*muxerFMP4Track, id int) *muxerFMP4Track {
type muxerFMP4 (line 33) | type muxerFMP4 struct
method writeInit (line 43) | func (w *muxerFMP4) writeInit(init *fmp4.Init) {
method setTrack (line 57) | func (w *muxerFMP4) setTrack(trackID int) {
method writeSample (line 61) | func (w *muxerFMP4) writeSample(
method writeFinalDTS (line 126) | func (w *muxerFMP4) writeFinalDTS(dts int64) {
method innerFlush (line 133) | func (w *muxerFMP4) innerFlush(final bool) error {
method flush (line 202) | func (w *muxerFMP4) flush() error {
FILE: internal/playback/muxer_mp4.go
type muxerMP4Track (line 11) | type muxerMP4Track struct
function findTrackMP4 (line 16) | func findTrackMP4(tracks []*muxerMP4Track, id int) *muxerMP4Track {
type muxerMP4 (line 25) | type muxerMP4 struct
method writeInit (line 32) | func (w *muxerMP4) writeInit(init *fmp4.Init) {
method setTrack (line 46) | func (w *muxerMP4) setTrack(trackID int) {
method writeSample (line 50) | func (w *muxerMP4) writeSample(
method writeFinalDTS (line 85) | func (w *muxerMP4) writeFinalDTS(dts int64) {
method flush (line 92) | func (w *muxerMP4) flush() error {
FILE: internal/playback/muxer_mp4_test.go
function TestMuxerMP4EmptyTracks (line 14) | func TestMuxerMP4EmptyTracks(t *testing.T) {
FILE: internal/playback/on_get.go
type writerWrapper (line 19) | type writerWrapper struct
method Write (line 24) | func (w *writerWrapper) Write(p []byte) (int, error) {
function parseDuration (line 33) | func parseDuration(raw string) (time.Duration, error) {
function seekAndMux (line 43) | func seekAndMux(
method onGet (line 122) | func (s *Server) onGet(ctx *gin.Context) {
FILE: internal/playback/on_get_test.go
function writeSegment1 (line 26) | func writeSegment1(t *testing.T, fpath string) {
function writeSegment2 (line 104) | func writeSegment2(t *testing.T, fpath string) {
function writeSegment3 (line 192) | func writeSegment3(t *testing.T, fpath string) {
function TestOnGet (line 232) | func TestOnGet(t *testing.T) {
function TestOnGetDifferentInit (line 702) | func TestOnGetDifferentInit(t *testing.T) {
function TestOnGetInMiddleOfLastSample (line 782) | func TestOnGetInMiddleOfLastSample(t *testing.T) {
function TestOnGetBetweenSegments (line 876) | func TestOnGetBetweenSegments(t *testing.T) {
FILE: internal/playback/on_list.go
type listEntryDuration (line 20) | type listEntryDuration
method MarshalJSON (line 22) | func (d listEntryDuration) MarshalJSON() ([]byte, error) {
type parsedSegment (line 26) | type parsedSegment struct
function parseSegment (line 32) | func parseSegment(seg *recordstore.Segment) (*parsedSegment, error) {
function parseSegments (line 60) | func parseSegments(segments []*recordstore.Segment) ([]*parsedSegment, e...
function urlScheme (line 87) | func urlScheme(ctx *gin.Context, trustedProxies conf.IPNetworks, encrypt...
type listEntry (line 102) | type listEntry struct
function concatenateSegments (line 108) | func concatenateSegments(parsed []*parsedSegment) []listEntry {
function parseAndConcatenate (line 134) | func parseAndConcatenate(
method onList (line 151) | func (s *Server) onList(ctx *gin.Context) {
FILE: internal/playback/on_list_test.go
function TestOnList (line 24) | func TestOnList(t *testing.T) {
function writeDuration (line 194) | func writeDuration(f io.ReadWriteSeeker, d time.Duration) error {
function TestOnListCachedDuration (line 258) | func TestOnListCachedDuration(t *testing.T) {
function TestOnListXForwardedProto (line 340) | func TestOnListXForwardedProto(t *testing.T) {
FILE: internal/playback/segment_fmp4.go
constant sampleFlagIsNonSyncSample (line 17) | sampleFlagIsNonSyncSample = 1 << 16
constant concatenationTolerance (line 18) | concatenationTolerance = 1 * time.Second
type readSeekerAt (line 23) | type readSeekerAt interface
function durationGoToMp4 (line 29) | func durationGoToMp4(v time.Duration, timeScale uint32) int64 {
function durationMp4ToGo (line 36) | func durationMp4ToGo(v int64, timeScale uint32) time.Duration {
function findInitTrack (line 43) | func findInitTrack(tracks []*fmp4.InitTrack, id int) *fmp4.InitTrack {
function findMtxi (line 52) | func findMtxi(userData []amp4.IBox) *recordstore.Mtxi {
function segmentFMP4TracksAreEqual (line 61) | func segmentFMP4TracksAreEqual(tracks1 []*fmp4.InitTrack, tracks2 []*fmp...
function segmentFMP4CanBeConcatenated (line 79) | func segmentFMP4CanBeConcatenated(
function segmentFMP4ReadHeader (line 106) | func segmentFMP4ReadHeader(r io.ReadSeeker) (*fmp4.Init, time.Duration, ...
function segmentFMP4ReadDurationFromParts (line 181) | func segmentFMP4ReadDurationFromParts(
function segmentFMP4MuxParts (line 418) | func segmentFMP4MuxParts(
FILE: internal/playback/segment_fmp4_test.go
function writeBenchInit (line 18) | func writeBenchInit(f io.WriteSeeker) {
function BenchmarkFMP4ReadHeader (line 56) | func BenchmarkFMP4ReadHeader(b *testing.B) {
function TestSegmentFMP4CanBeConcatenated (line 82) | func TestSegmentFMP4CanBeConcatenated(t *testing.T) {
FILE: internal/playback/server.go
type serverAuthManager (line 18) | type serverAuthManager interface
type Server (line 23) | type Server struct
method Initialize (line 42) | func (s *Server) Initialize() error {
method Close (line 75) | func (s *Server) Close() {
method Log (line 81) | func (s *Server) Log(level logger.Level, format string, args ...any) {
method ReloadPathConfs (line 86) | func (s *Server) ReloadPathConfs(pathConfs map[string]*conf.Path) {
method writeError (line 92) | func (s *Server) writeError(ctx *gin.Context, status int, err error) {
method safeFindPathConf (line 100) | func (s *Server) safeFindPathConf(name string) (*conf.Path, error) {
method middlewarePreflightRequests (line 108) | func (s *Server) middlewarePreflightRequests(ctx *gin.Context) {
method doAuth (line 118) | func (s *Server) doAuth(ctx *gin.Context, pathName string) bool {
FILE: internal/playback/server_test.go
function TestPreflightRequest (line 18) | func TestPreflightRequest(t *testing.T) {
function TestAuthError (line 55) | func TestAuthError(t *testing.T) {
FILE: internal/pprof/pprof.go
type pprofAuthManager (line 19) | type pprofAuthManager interface
type pprofParent (line 23) | type pprofParent interface
type PPROF (line 28) | type PPROF struct
method Initialize (line 45) | func (pp *PPROF) Initialize() error {
method Close (line 78) | func (pp *PPROF) Close() {
method Log (line 84) | func (pp *PPROF) Log(level logger.Level, format string, args ...any) {
method middlewarePreflightRequests (line 88) | func (pp *PPROF) middlewarePreflightRequests(ctx *gin.Context) {
method middlewareAuth (line 98) | func (pp *PPROF) middlewareAuth(ctx *gin.Context) {
FILE: internal/pprof/pprof_test.go
function TestPreflightRequest (line 17) | func TestPreflightRequest(t *testing.T) {
function TestPprof (line 54) | func TestPprof(t *testing.T) {
function TestAuthError (line 97) | func TestAuthError(t *testing.T) {
FILE: internal/protocols/hls/from_stream.go
function setupVideoTrack (line 23) | func setupVideoTrack(
function setupAudioTracks (line 180) | func setupAudioTracks(
function FromStream (line 290) | func FromStream(
FILE: internal/protocols/hls/from_stream_test.go
function TestFromStreamNoSupportedCodecs (line 16) | func TestFromStreamNoSupportedCodecs(t *testing.T) {
function TestFromStreamSkipUnsupportedTracks (line 34) | func TestFromStreamSkipUnsupportedTracks(t *testing.T) {
FILE: internal/protocols/hls/to_stream.go
type ntpState (line 17) | type ntpState
constant ntpStateInitial (line 20) | ntpStateInitial ntpState = iota
constant ntpStateUnavailable (line 21) | ntpStateUnavailable
constant ntpStateAvailable (line 22) | ntpStateAvailable
constant ntpStateReplace (line 23) | ntpStateReplace
function multiplyAndDivide (line 26) | func multiplyAndDivide(v, m, d int64) int64 {
function ToStream (line 33) | func ToStream(
FILE: internal/protocols/hls/to_stream_test.go
function TestToStreamNoSupportedCodecs (line 22) | func TestToStreamNoSupportedCodecs(t *testing.T) {
function TestToStream (line 30) | func TestToStream(t *testing.T) {
FILE: internal/protocols/httpp/content_type.go
function ParseContentType (line 6) | func ParseContentType(v string) string {
FILE: internal/protocols/httpp/credentials.go
function Credentials (line 11) | func Credentials(h *http.Request) *auth.Credentials {
FILE: internal/protocols/httpp/credentials_test.go
function TestCredentials (line 12) | func TestCredentials(t *testing.T) {
FILE: internal/protocols/httpp/handler_exit_on_panic.go
type handlerExitOnPanic (line 12) | type handlerExitOnPanic struct
method ServeHTTP (line 16) | func (h *handlerExitOnPanic) ServeHTTP(w http.ResponseWriter, r *http....
FILE: internal/protocols/httpp/handler_filter_requests.go
type handlerFilterRequests (line 8) | type handlerFilterRequests struct
method ServeHTTP (line 12) | func (h *handlerFilterRequests) ServeHTTP(w http.ResponseWriter, r *ht...
FILE: internal/protocols/httpp/handler_filter_requests_test.go
function TestHandlerFilterRequests (line 14) | func TestHandlerFilterRequests(t *testing.T) {
FILE: internal/protocols/httpp/handler_logger.go
type loggerWriter (line 12) | type loggerWriter struct
method Header (line 18) | func (w *loggerWriter) Header() http.Header {
method Write (line 22) | func (w *loggerWriter) Write(b []byte) (int, error) {
method WriteHeader (line 30) | func (w *loggerWriter) WriteHeader(statusCode int) {
method dump (line 35) | func (w *loggerWriter) dump() string {
type handlerLogger (line 47) | type handlerLogger struct
method ServeHTTP (line 52) | func (h *handlerLogger) ServeHTTP(w http.ResponseWriter, r *http.Reque...
FILE: internal/protocols/httpp/handler_origin.go
function isOriginAllowed (line 11) | func isOriginAllowed(origin string, allowOrigins []string) (string, bool) {
type handlerOrigin (line 75) | type handlerOrigin struct
method ServeHTTP (line 80) | func (h *handlerOrigin) ServeHTTP(w http.ResponseWriter, r *http.Reque...
FILE: internal/protocols/httpp/handler_origin_test.go
function TestHandlerOrigin (line 12) | func TestHandlerOrigin(t *testing.T) {
FILE: internal/protocols/httpp/handler_server_header.go
type handlerServerHeader (line 8) | type handlerServerHeader struct
method ServeHTTP (line 12) | func (h *handlerServerHeader) ServeHTTP(w http.ResponseWriter, r *http...
FILE: internal/protocols/httpp/handler_tracker.go
type handlerTracker (line 8) | type handlerTracker struct
method close (line 16) | func (h *handlerTracker) close() {
method ServeHTTP (line 23) | func (h *handlerTracker) ServeHTTP(w http.ResponseWriter, r *http.Requ...
FILE: internal/protocols/httpp/handler_tracker_test.go
function TestHandlerTracker (line 12) | func TestHandlerTracker(t *testing.T) {
FILE: internal/protocols/httpp/handler_write_timeout.go
type writeTimeoutWriter (line 8) | type writeTimeoutWriter struct
method Header (line 14) | func (w *writeTimeoutWriter) Header() http.Header {
method Write (line 18) | func (w *writeTimeoutWriter) Write(p []byte) (int, error) {
method WriteHeader (line 23) | func (w *writeTimeoutWriter) WriteHeader(statusCode int) {
type handlerWriteTimeout (line 31) | type handlerWriteTimeout struct
method ServeHTTP (line 36) | func (h *handlerWriteTimeout) ServeHTTP(w http.ResponseWriter, r *http...
FILE: internal/protocols/httpp/remote_addr.go
function RemoteAddr (line 11) | func RemoteAddr(ctx *gin.Context) string {
FILE: internal/protocols/httpp/server.go
type nilWriter (line 20) | type nilWriter struct
method Write (line 22) | func (nilWriter) Write(p []byte) (int, error) {
type Server (line 33) | type Server struct
method Initialize (line 53) | func (s *Server) Initialize() error {
method Close (line 146) | func (s *Server) Close() {
FILE: internal/protocols/httpp/server_test.go
function TestUnixSocket (line 16) | func TestUnixSocket(t *testing.T) {
FILE: internal/protocols/mpegts/enhanced_reader.go
type EnhancedReader (line 15) | type EnhancedReader struct
method Initialize (line 24) | func (r *EnhancedReader) Initialize() error {
FILE: internal/protocols/mpegts/from_stream.go
function multiplyAndDivide (line 25) | func multiplyAndDivide(v, m, d int64) int64 {
function FromStream (line 32) | func FromStream(
FILE: internal/protocols/mpegts/from_stream_test.go
function TestFromStreamNoSupportedCodecs (line 15) | func TestFromStreamNoSupportedCodecs(t *testing.T) {
function TestFromStreamSkipUnsupportedTracks (line 31) | func TestFromStreamSkipUnsupportedTracks(t *testing.T) {
FILE: internal/protocols/mpegts/to_stream.go
function ToStream (line 25) | func ToStream(
FILE: internal/protocols/mpegts/to_stream_test.go
function TestToStream (line 18) | func TestToStream(t *testing.T) {
function TestToStreamNoSupportedCodecs (line 153) | func TestToStreamNoSupportedCodecs(t *testing.T) {
function TestToStreamSkipUnsupportedTracks (line 179) | func TestToStreamSkipUnsupportedTracks(t *testing.T) {
FILE: internal/protocols/rtmp/from_stream.go
function multiplyAndDivide2 (line 30) | func multiplyAndDivide2(v, m, d time.Duration) time.Duration {
function timestampToDuration (line 36) | func timestampToDuration(t int64, clockRate int) time.Duration {
function FromStream (line 41) | func FromStream(
FILE: internal/protocols/rtmp/from_stream_test.go
function TestFromStream (line 54) | func TestFromStream(t *testing.T) {
function TestFromStreamLegacyClientMultipleTracks (line 634) | func TestFromStreamLegacyClientMultipleTracks(t *testing.T) {
function TestFromStreamNoSupportedCodecs (line 791) | func TestFromStreamNoSupportedCodecs(t *testing.T) {
function TestFromStreamSkipUnsupportedTracks (line 809) | func TestFromStreamSkipUnsupportedTracks(t *testing.T) {
FILE: internal/protocols/rtmp/to_stream.go
function multiplyAndDivide (line 20) | func multiplyAndDivide(v, m, d int64) int64 {
function durationToTimestamp (line 26) | func durationToTimestamp(d time.Duration, clockRate int) int64 {
function fourCCToString (line 30) | func fourCCToString(c message.FourCC) string {
function ToStream (line 35) | func ToStream(
FILE: internal/protocols/rtmp/to_stream_test.go
function TestToStreamNoSupportedCodecs (line 10) | func TestToStreamNoSupportedCodecs(t *testing.T) {
FILE: internal/protocols/rtsp/credentials.go
function Credentials (line 10) | func Credentials(rt *base.Request) *auth.Credentials {
FILE: internal/protocols/rtsp/credentials_test.go
function TestCredentials (line 11) | func TestCredentials(t *testing.T) {
FILE: internal/protocols/rtsp/to_stream.go
type ntpState (line 17) | type ntpState
constant ntpStateInitial (line 20) | ntpStateInitial ntpState = iota
constant ntpStateReplace (line 21) | ntpStateReplace
constant ntpStateAvailable (line 22) | ntpStateAvailable
type rtspSource (line 25) | type rtspSource interface
function ToStream (line 32) | func ToStream(
FILE: internal/protocols/tls/make_config.go
function MakeConfig (line 15) | func MakeConfig(serverName string, fingerprint string) *tls.Config {
FILE: internal/protocols/tls/make_config_test.go
function TestMakeConfigSNI (line 63) | func TestMakeConfigSNI(t *testing.T) {
function TestMakeConfigFingerprint (line 101) | func TestMakeConfigFingerprint(t *testing.T) {
FILE: internal/protocols/udp/listener.go
type packetConn (line 15) | type packetConn interface
function defaultInterfaceForMulticast (line 21) | func defaultInterfaceForMulticast(multicastAddr *net.UDPAddr) (*net.Inte...
type Listener (line 60) | type Listener struct
method Initialize (line 72) | func (l *Listener) Initialize() error {
method Close (line 129) | func (l *Listener) Close() error {
method Read (line 134) | func (l *Listener) Read(p []byte) (int, error) {
method Write (line 147) | func (l *Listener) Write(_ []byte) (int, error) {
method LocalAddr (line 152) | func (l *Listener) LocalAddr() net.Addr {
method RemoteAddr (line 157) | func (l *Listener) RemoteAddr() net.Addr {
method SetDeadline (line 162) | func (l *Listener) SetDeadline(_ time.Time) error {
method SetReadDeadline (line 167) | func (l *Listener) SetReadDeadline(t time.Time) error {
method SetWriteDeadline (line 172) | func (l *Listener) SetWriteDeadline(_ time.Time) error {
FILE: internal/protocols/udp/listener_test.go
function TestListen (line 11) | func TestListen(t *testing.T) {
FILE: internal/protocols/udp/params.go
type Params (line 6) | type Params struct
function URLToParams (line 13) | func URLToParams(u *url.URL) *Params {
FILE: internal/protocols/unix/listener.go
type Listener (line 13) | type Listener struct
method Initialize (line 24) | func (l *Listener) Initialize() error {
method Close (line 41) | func (l *Listener) Close() error {
method acceptWithDeadline (line 56) | func (l *Listener) acceptWithDeadline() (net.Conn, error) {
method setConn (line 83) | func (l *Listener) setConn(c net.Conn) error {
method Read (line 95) | func (l *Listener) Read(p []byte) (int, error) {
method Write (line 113) | func (l *Listener) Write(_ []byte) (int, error) {
method LocalAddr (line 118) | func (l *Listener) LocalAddr() net.Addr {
method RemoteAddr (line 123) | func (l *Listener) RemoteAddr() net.Addr {
method SetDeadline (line 128) | func (l *Listener) SetDeadline(_ time.Time) error {
method SetReadDeadline (line 133) | func (l *Listener) SetReadDeadline(t time.Time) error {
method SetWriteDeadline (line 139) | func (l *Listener) SetWriteDeadline(_ time.Time) error {
FILE: internal/protocols/unix/listener_test.go
function TestListen (line 12) | func TestListen(t *testing.T) {
FILE: internal/protocols/unix/params.go
type Params (line 6) | type Params struct
function URLToParams (line 11) | func URLToParams(u *url.URL) *Params {
FILE: internal/protocols/webrtc/from_stream.go
constant webrtcPayloadMaxSize (line 28) | webrtcPayloadMaxSize = 1188
function ptrOf (line 44) | func ptrOf[T any](v T) *T {
function randUint32 (line 50) | func randUint32() (uint32, error) {
function multiplyAndDivide2 (line 59) | func multiplyAndDivide2(v, m, d time.Duration) time.Duration {
function timestampToDuration (line 65) | func timestampToDuration(t int64, clockRate int) time.Duration {
function setupVideoTrack (line 69) | func setupVideoTrack(
function setupAudioTrack (line 325) | func setupAudioTrack(
function setupKLVDataChannel (line 641) | func setupKLVDataChannel(
function FromStream (line 672) | func FromStream(
FILE: internal/protocols/webrtc/from_stream_test.go
function TestFromStreamNoSupportedCodecs (line 18) | func TestFromStreamNoSupportedCodecs(t *testing.T) {
function TestFromStreamSkipUnsupportedTracks (line 36) | func TestFromStreamSkipUnsupportedTracks(t *testing.T) {
function TestFromStream (line 68) | func TestFromStream(t *testing.T) {
function TestFromStreamResampleOpus (line 88) | func TestFromStreamResampleOpus(t *testing.T) {
FILE: internal/protocols/webrtc/incoming_track.go
constant keyFrameInterval (line 16) | keyFrameInterval = 2 * time.Second
constant mimeTypeMultiopus (line 17) | mimeTypeMultiopus = "audio/multiopus"
constant mimeTypeL16 (line 18) | mimeTypeL16 = "audio/L16"
type IncomingTrack (line 238) | type IncomingTrack struct
method initialize (line 251) | func (t *IncomingTrack) initialize() {
method Codec (line 256) | func (t *IncomingTrack) Codec() webrtc.RTPCodecParameters {
method ClockRate (line 261) | func (t *IncomingTrack) ClockRate() int {
method PTSEqualsDTS (line 266) | func (*IncomingTrack) PTSEqualsDTS(*rtp.Packet) bool {
method start (line 270) | func (t *IncomingTrack) start() {
method PacketNTP (line 368) | func (t *IncomingTrack) PacketNTP(pkt *rtp.Packet) (time.Time, bool) {
method close (line 372) | func (t *IncomingTrack) close() {
FILE: internal/protocols/webrtc/net.go
type webrtcNet (line 11) | type webrtcNet struct
method initialize (line 17) | func (n *webrtcNet) initialize() error {
method ListenUDP (line 27) | func (n *webrtcNet) ListenUDP(network string, laddr *net.UDPAddr) (tra...
FILE: internal/protocols/webrtc/outgoing_data_channel.go
type OutgoingDataChannel (line 8) | type OutgoingDataChannel struct
method setup (line 14) | func (c *OutgoingDataChannel) setup(p *PeerConnection) error {
method Write (line 27) | func (c *OutgoingDataChannel) Write(data []byte) {
FILE: internal/protocols/webrtc/outgoing_track.go
type OutgoingTrack (line 14) | type OutgoingTrack struct
method isVideo (line 22) | func (t *OutgoingTrack) isVideo() bool {
method setup (line 26) | func (t *OutgoingTrack) setup(p *PeerConnection) error {
method close (line 80) | func (t *OutgoingTrack) close() {
method WriteRTP (line 87) | func (t *OutgoingTrack) WriteRTP(pkt *rtp.Packet) error {
method WriteRTPWithNTP (line 92) | func (t *OutgoingTrack) WriteRTPWithNTP(pkt *rtp.Packet, ntp time.Time...
FILE: internal/protocols/webrtc/peer_connection.go
constant webrtcStreamID (line 25) | webrtcStreamID = "mediamtx"
function interfaceIPs (line 28) | func interfaceIPs(interfaceList []string) ([]string, error) {
function maxTrackCount (line 62) | func maxTrackCount(medias []*sdp.MediaDescription) int {
function registerInterceptors (line 83) | func registerInterceptors(
function candidateLabel (line 110) | func candidateLabel(c *webrtc.ICECandidate) string {
function TracksAreValid (line 116) | func TracksAreValid(medias []*sdp.MediaDescription) error {
type trackRecvPair (line 146) | type trackRecvPair struct
type PeerConnection (line 152) | type PeerConnection struct
method Start (line 185) | func (co *PeerConnection) Start() error {
method Close (line 442) | func (co *PeerConnection) Close() {
method run (line 447) | func (co *PeerConnection) run() {
method removeUnwantedCandidates (line 481) | func (co *PeerConnection) removeUnwantedCandidates(firstMedia *sdp.Med...
method addAdditionalCandidates (line 516) | func (co *PeerConnection) addAdditionalCandidates(firstMedia *sdp.Medi...
method filterLocalDescription (line 590) | func (co *PeerConnection) filterLocalDescription(desc *webrtc.SessionD...
method CreatePartialOffer (line 613) | func (co *PeerConnection) CreatePartialOffer() (*webrtc.SessionDescrip...
method SetAnswer (line 634) | func (co *PeerConnection) SetAnswer(answer *webrtc.SessionDescription)...
method AddRemoteCandidate (line 639) | func (co *PeerConnection) AddRemoteCandidate(candidate *webrtc.ICECand...
method CreateFullAnswer (line 644) | func (co *PeerConnection) CreateFullAnswer(offer *webrtc.SessionDescri...
method waitGatheringDone (line 679) | func (co *PeerConnection) waitGatheringDone() error {
method WaitUntilConnected (line 692) | func (co *PeerConnection) WaitUntilConnected(timeout time.Duration) er...
method GatherIncomingTracks (line 714) | func (co *PeerConnection) GatherIncomingTracks(timeout time.Duration) ...
method Connected (line 756) | func (co *PeerConnection) Connected() <-chan struct{} {
method Failed (line 761) | func (co *PeerConnection) Failed() <-chan struct{} {
method NewLocalCandidate (line 766) | func (co *PeerConnection) NewLocalCandidate() <-chan *webrtc.ICECandid...
method GatheringDone (line 771) | func (co *PeerConnection) GatheringDone() <-chan struct{} {
method IncomingTracks (line 776) | func (co *PeerConnection) IncomingTracks() []*IncomingTrack {
method StartReading (line 781) | func (co *PeerConnection) StartReading() {
method LocalCandidate (line 789) | func (co *PeerConnection) LocalCandidate() string {
method RemoteCandidate (line 804) | func (co *PeerConnection) RemoteCandidate() string {
method Stats (line 830) | func (co *PeerConnection) Stats() *Stats {
function bytesStats (line 818) | func bytesStats(wr *webrtc.PeerConnection) (uint64, uint64) {
FILE: internal/protocols/webrtc/peer_connection_test.go
type nilWriter (line 21) | type nilWriter struct
method Write (line 23) | func (nilWriter) Write(p []byte) (int, error) {
function gatherCodecs (line 29) | func gatherCodecs(tracks []*IncomingTrack) []webrtc.RTPCodecParameters {
function TestPeerConnectionCloseImmediately (line 37) | func TestPeerConnectionCloseImmediately(t *testing.T) {
function TestPeerConnectionCloseImmediately2 (line 49) | func TestPeerConnectionCloseImmediately2(t *testing.T) {
function TestPeerConnectionCandidates (line 67) | func TestPeerConnectionCandidates(t *testing.T) {
function TestPeerConnectionConnectivity (line 164) | func TestPeerConnectionConnectivity(t *testing.T) {
function TestPeerConnectionRead (line 280) | func TestPeerConnectionRead(t *testing.T) {
function TestPeerConnectionReadSimulcast (line 427) | func TestPeerConnectionReadSimulcast(t *testing.T) {
function TestPeerConnectionPublishRead (line 580) | func TestPeerConnectionPublishRead(t *testing.T) {
function TestPeerConnectionFallbackCodecs (line 679) | func TestPeerConnectionFallbackCodecs(t *testing.T) {
function TestPeerConnectionPublishDataChannel (line 740) | func TestPeerConnectionPublishDataChannel(t *testing.T) {
FILE: internal/protocols/webrtc/stats.go
type Stats (line 4) | type Stats struct
FILE: internal/protocols/webrtc/stats_interceptor.go
type statsInterceptor (line 10) | type statsInterceptor struct
method Close (line 15) | func (*statsInterceptor) Close() error {
method BindRTCPReader (line 19) | func (s *statsInterceptor) BindRTCPReader(reader interceptor.RTCPReade...
method BindRTCPWriter (line 34) | func (s *statsInterceptor) BindRTCPWriter(writer interceptor.RTCPWrite...
method BindLocalStream (line 41) | func (s *statsInterceptor) BindLocalStream(_ *interceptor.StreamInfo,
method UnbindLocalStream (line 47) | func (*statsInterceptor) UnbindLocalStream(_ *interceptor.StreamInfo) {}
method BindRemoteStream (line 49) | func (s *statsInterceptor) BindRemoteStream(_ *interceptor.StreamInfo,
method UnbindRemoteStream (line 55) | func (*statsInterceptor) UnbindRemoteStream(_ *interceptor.StreamInfo) {}
type statsInterceptorFactory (line 57) | type statsInterceptorFactory struct
method NewInterceptor (line 61) | func (f *statsInterceptorFactory) NewInterceptor(_ string) (intercepto...
FILE: internal/protocols/webrtc/tcp_mux_wrapper.go
type TCPMuxWrapper (line 10) | type TCPMuxWrapper struct
FILE: internal/protocols/webrtc/to_stream.go
type ntpState (line 20) | type ntpState
constant ntpStateInitial (line 23) | ntpStateInitial ntpState = iota
constant ntpStateReplace (line 24) | ntpStateReplace
constant ntpStateAvailable (line 25) | ntpStateAvailable
function ToStream (line 33) | func ToStream(
FILE: internal/protocols/webrtc/to_stream_test.go
function TestToStreamNoSupportedCodecs (line 16) | func TestToStreamNoSupportedCodecs(t *testing.T) {
function TestToStream (line 334) | func TestToStream(t *testing.T) {
FILE: internal/protocols/websocket/serverconn.go
type ServerConn (line 28) | type ServerConn struct
method Close (line 59) | func (c *ServerConn) Close() {
method RemoteAddr (line 65) | func (c *ServerConn) RemoteAddr() net.Addr {
method run (line 69) | func (c *ServerConn) run() {
method ReadJSON (line 98) | func (c *ServerConn) ReadJSON(in any) error {
method WriteJSON (line 103) | func (c *ServerConn) WriteJSON(in any) error {
function NewServerConn (line 40) | func NewServerConn(w http.ResponseWriter, req *http.Request) (*ServerCon...
FILE: internal/protocols/websocket/serverconn_test.go
function TestServerConn (line 14) | func TestServerConn(t *testing.T) {
FILE: internal/protocols/whip/client.go
type Client (line 22) | type Client struct
method Initialize (line 39) | func (c *Client) Initialize(ctx context.Context) error {
method initializeInner (line 93) | func (c *Client) initializeInner(ctx context.Context) error {
method PeerConnection (line 166) | func (c *Client) PeerConnection() *webrtc.PeerConnection {
method IncomingTracks (line 171) | func (c *Client) IncomingTracks() []*webrtc.IncomingTrack {
method StartReading (line 176) | func (c *Client) StartReading() {
method Close (line 181) | func (c *Client) Close() error {
method Wait (line 188) | func (c *Client) Wait() error {
method optionsICEServers (line 193) | func (c *Client) optionsICEServers(
method postOffer (line 224) | func (c *Client) postOffer(
method patchCandidate (line 280) | func (c *Client) patchCandidate(
method deleteSession (line 320) | func (c *Client) deleteSession(
type whipPostOfferResponse (line 218) | type whipPostOfferResponse struct
FILE: internal/protocols/whip/client_test.go
function whipOffer (line 20) | func whipOffer(body []byte) *pwebrtc.SessionDescription {
function gatherCodecs (line 27) | func gatherCodecs(tracks []*webrtc.IncomingTrack) []pwebrtc.RTPCodecPara...
function TestClientRead (line 35) | func TestClientRead(t *testing.T) {
function TestClientPublish (line 238) | func TestClientPublish(t *testing.T) {
function TestClientBearerToken (line 439) | func TestClientBearerToken(t *testing.T) {
FILE: internal/protocols/whip/ice_fragment.go
function ICEFragmentUnmarshal (line 12) | func ICEFragmentUnmarshal(buf []byte) ([]*webrtc.ICECandidateInit, error) {
function ICEFragmentMarshal (line 51) | func ICEFragmentMarshal(offer string, candidates []*webrtc.ICECandidateI...
FILE: internal/protocols/whip/ice_fragment_test.go
function ptrOf (line 10) | func ptrOf[T any](v T) *T {
function TestICEFragmentUnmarshal (line 188) | func TestICEFragmentUnmarshal(t *testing.T) {
function TestICEFragmentMarshal (line 198) | func TestICEFragmentMarshal(t *testing.T) {
FILE: internal/protocols/whip/link_header.go
function quoteCredential (line 11) | func quoteCredential(v string) string {
function unquoteCredential (line 17) | func unquoteCredential(v string) string {
function LinkHeaderMarshal (line 24) | func LinkHeaderMarshal(iceServers []webrtc.ICEServer) []string {
function LinkHeaderUnmarshal (line 43) | func LinkHeaderUnmarshal(link []string) ([]webrtc.ICEServer, error) {
FILE: internal/protocols/whip/link_header_test.go
function TestLinkHeaderUnmarshal (line 35) | func TestLinkHeaderUnmarshal(t *testing.T) {
function TestLinkHeaderMarshal (line 45) | func TestLinkHeaderMarshal(t *testing.T) {
FILE: internal/recordcleaner/cleaner.go
type Cleaner (line 20) | type Cleaner struct
method Initialize (line 32) | func (c *Cleaner) Initialize() {
method Close (line 41) | func (c *Cleaner) Close() {
method Log (line 47) | func (c *Cleaner) Log(level logger.Level, format string, args ...any) {
method ReloadPathConfs (line 52) | func (c *Cleaner) ReloadPathConfs(pathConfs map[string]*conf.Path) {
method run (line 59) | func (c *Cleaner) run() {
method cleanInterval (line 78) | func (c *Cleaner) cleanInterval() time.Duration {
method doRun (line 91) | func (c *Cleaner) doRun() {
method processPath (line 101) | func (c *Cleaner) processPath(now time.Time, pathName string) error {
method deleteExpiredSegments (line 121) | func (c *Cleaner) deleteExpiredSegments(now time.Time, pathName string...
method deleteEmptyDirs (line 136) | func (c *Cleaner) deleteEmptyDirs(pathConf *conf.Path) {
FILE: internal/recordcleaner/cleaner_test.go
function TestCleaner (line 15) | func TestCleaner(t *testing.T) {
function TestCleanerMultipleEntriesSamePath (line 59) | func TestCleanerMultipleEntriesSamePath(t *testing.T) {
FILE: internal/recorder/format.go
type format (line 3) | type format interface
FILE: internal/recorder/format_fmp4.go
function mpeg1audioChannelCount (line 79) | func mpeg1audioChannelCount(cm mpeg1audio.ChannelMode) int {
function jpegExtractSize (line 91) | func jpegExtractSize(image []byte) (int, int, error) {
type formatFMP4Sample (line 146) | type formatFMP4Sample struct
type formatFMP4 (line 152) | type formatFMP4 struct
method initialize (line 161) | func (f *formatFMP4) initialize() bool {
method updateCodecParams (line 936) | func (f *formatFMP4) updateCodecParams() {
method close (line 940) | func (f *formatFMP4) close() {
FILE: internal/recorder/format_fmp4_part.go
function writePart (line 13) | func writePart(
type formatFMP4Part (line 40) | type formatFMP4Part struct
method initialize (line 51) | func (p *formatFMP4Part) initialize() {
method close (line 55) | func (p *formatFMP4Part) close(w io.Writer) error {
method write (line 59) | func (p *formatFMP4Part) write(track *formatFMP4Track, sample *formatF...
method duration (line 86) | func (p *formatFMP4Part) duration() time.Duration {
FILE: internal/recorder/format_fmp4_segment.go
function writeInit (line 19) | func writeInit(
function writeDuration (line 57) | func writeDuration(f io.ReadWriteSeeker, d time.Duration) error {
type formatFMP4Segment (line 121) | type formatFMP4Segment struct
method initialize (line 134) | func (s *formatFMP4Segment) initialize() {
method close (line 138) | func (s *formatFMP4Segment) close() error {
method closeCurPart (line 168) | func (s *formatFMP4Segment) closeCurPart() error {
method write (line 203) | func (s *formatFMP4Segment) write(track *formatFMP4Track, sample *form...
FILE: internal/recorder/format_fmp4_track.go
constant maxBasetime (line 14) | maxBasetime = 1 * time.Second
function nextSegmentStartingPos (line 19) | func nextSegmentStartingPos(tracks []*formatFMP4Track) (time.Time, time....
type formatFMP4Track (line 46) | type formatFMP4Track struct
method initialize (line 59) | func (t *formatFMP4Track) initialize() {
method write (line 67) | func (t *formatFMP4Track) write(sample *formatFMP4Sample) error {
FILE: internal/recorder/format_mpegts.go
constant mpegtsBufferSize (line 26) | mpegtsBufferSize = 64 * 1024
function multiplyAndDivide (line 29) | func multiplyAndDivide(v, m, d int64) int64 {
function multiplyAndDivide2 (line 35) | func multiplyAndDivide2(v, m, d time.Duration) time.Duration {
function timestampToDuration (line 41) | func timestampToDuration(t int64, clockRate int) time.Duration {
type dynamicWriter (line 45) | type dynamicWriter struct
method Write (line 49) | func (d *dynamicWriter) Write(p []byte) (int, error) {
method setTarget (line 53) | func (d *dynamicWriter) setTarget(w io.Writer) {
type formatMPEGTS (line 57) | type formatMPEGTS struct
method initialize (line 67) | func (f *formatMPEGTS) initialize() bool {
method close (line 448) | func (f *formatMPEGTS) close() {
FILE: internal/recorder/format_mpegts_segment.go
type formatMPEGTSSegment (line 12) | type formatMPEGTSSegment struct
method initialize (line 27) | func (s *formatMPEGTSSegment) initialize() {
method close (line 32) | func (s *formatMPEGTSSegment) close() error {
method Write (line 51) | func (s *formatMPEGTSSegment) Write(p []byte) (int, error) {
FILE: internal/recorder/format_mpegts_track.go
type formatMPEGTSTrack (line 11) | type formatMPEGTSTrack struct
method initialize (line 21) | func (t *formatMPEGTSTrack) initialize() {
method write (line 27) | func (t *formatMPEGTSTrack) write(
FILE: internal/recorder/recorder.go
constant ntpDriftTolerance (line 13) | ntpDriftTolerance = 5 * time.Second
type Recorder (line 23) | type Recorder struct
method Initialize (line 44) | func (r *Recorder) Initialize() {
method Log (line 78) | func (r *Recorder) Log(level logger.Level, format string, args ...any) {
method Close (line 83) | func (r *Recorder) Close() {
method run (line 89) | func (r *Recorder) run() {
FILE: internal/recorder/recorder_instance.go
type recorderInstance (line 15) | type recorderInstance struct
method Log (line 38) | func (ri *recorderInstance) Log(level logger.Level, format string, arg...
method initialize (line 42) | func (ri *recorderInstance) initialize() {
method close (line 80) | func (ri *recorderInstance) close() {
method run (line 85) | func (ri *recorderInstance) run() {
FILE: internal/recorder/recorder_test.go
function TestRecorder (line 26) | func TestRecorder(t *testing.T) {
function TestRecorderFMP4NegativeInitialDTS (line 402) | func TestRecorderFMP4NegativeInitialDTS(t *testing.T) {
function TestRecorderFMP4NegativeDTSDiff (line 504) | func TestRecorderFMP4NegativeDTSDiff(t *testing.T) {
function TestRecorderSkipTracksPartial (line 608) | func TestRecorderSkipTracksPartial(t *testing.T) {
function TestRecorderSkipTracksFull (line 680) | func TestRecorderSkipTracksFull(t *testing.T) {
function TestRecorderFMP4SegmentSwitch (line 748) | func TestRecorderFMP4SegmentSwitch(t *testing.T) {
function TestRecorderTimeDriftDetector (line 862) | func TestRecorderTimeDriftDetector(t *testing.T) {
FILE: internal/recordstore/mp4_boxes.go
function boxTypeMtxi (line 7) | func boxTypeMtxi() amp4.BoxType { return amp4.StrToBoxType("mtxi") }
function init (line 9) | func init() { //nolint:gochecknoinits
type Mtxi (line 14) | type Mtxi struct
method GetType (line 23) | func (*Mtxi) GetType() amp4.BoxType {
FILE: internal/recordstore/path.go
function leadingZeros (line 12) | func leadingZeros(v int, size int) string {
function timeLocationEncode (line 26) | func timeLocationEncode(t time.Time) string {
function timeLocationDecode (line 48) | func timeLocationDecode(s string) *time.Location {
function PathAddExtension (line 69) | func PathAddExtension(path string, format conf.RecordFormat) string {
function CommonPath (line 80) | func CommonPath(v string) string {
type Path (line 108) | type Path struct
method Decode (line 114) | func (p *Path) Decode(format string, v string) bool {
method Encode (line 250) | func (p Path) Encode(format string) string {
FILE: internal/recordstore/path_test.go
function TestPathDecode (line 72) | func TestPathDecode(t *testing.T) {
function TestPathEncode (line 83) | func TestPathEncode(t *testing.T) {
FILE: internal/recordstore/segment.go
type Segment (line 20) | type Segment struct
function fixedPathHasSegments (line 25) | func fixedPathHasSegments(pathConf *conf.Path) bool {
function regexpPathFindPathsWithSegments (line 59) | func regexpPathFindPathsWithSegments(pathConf *conf.Path) map[string]str...
function FindAllPathsWithSegments (line 96) | func FindAllPathsWithSegments(pathConfs map[string]*conf.Path) []string {
function FindSegments (line 124) | func FindSegments(
FILE: internal/recordstore/segment_test.go
function ptrOf (line 14) | func ptrOf[T any](v T) *T {
function TestFindAllPathsWithSegments (line 20) | func TestFindAllPathsWithSegments(t *testing.T) {
function TestFindAllPathsWithSegmentsInvalidPath (line 53) | func TestFindAllPathsWithSegmentsInvalidPath(t *testing.T) {
function TestFindSegments (line 72) | func TestFindSegments(t *testing.T) {
FILE: internal/restrictnetwork/restrict_network.go
function Restrict (line 9) | func Restrict(network string, address string) (string, string) {
FILE: internal/rlimit/rlimit_unix.go
function Raise (line 11) | func Raise() error {
FILE: internal/rlimit/rlimit_win.go
function Raise (line 5) | func Raise() error {
FILE: internal/servers/hls/hlsjsdownloader/main.go
function do (line 18) | func do() error {
function main (line 75) | func main() {
FILE: internal/servers/hls/http_server.go
function mergePathAndQuery (line 29) | func mergePathAndQuery(path string, rawQuery string) string {
type httpServer (line 37) | type httpServer struct
method initialize (line 53) | func (s *httpServer) initialize() error {
method Log (line 83) | func (s *httpServer) Log(level logger.Level, format string, args ...an...
method close (line 87) | func (s *httpServer) close() {
method middlewarePreflightRequests (line 91) | func (s *httpServer) middlewarePreflightRequests(ctx *gin.Context) {
method onRequest (line 101) | func (s *httpServer) onRequest(ctx *gin.Context) {
FILE: internal/servers/hls/muxer.go
constant closeCheckPeriod (line 21) | closeCheckPeriod = 1 * time.Second
constant recreatePause (line 22) | recreatePause = 10 * time.Second
function ptrOf (line 25) | func ptrOf[T any](v T) *T {
function emptyTimer (line 31) | func emptyTimer() *time.Timer {
type responseWriterWithCounter (line 37) | type responseWriterWithCounter struct
method Write (line 42) | func (w *responseWriterWithCounter) Write(p []byte) (int, error) {
type muxerGetInstanceRes (line 48) | type muxerGetInstanceRes struct
type muxerGetInstanceReq (line 53) | type muxerGetInstanceReq struct
type muxer (line 57) | type muxer struct
method initialize (line 84) | func (m *muxer) initialize() {
method Close (line 105) | func (m *muxer) Close() {
method Log (line 110) | func (m *muxer) Log(level logger.Level, format string, args ...any) {
method PathName (line 115) | func (m *muxer) PathName() string {
method run (line 119) | func (m *muxer) run() {
method runInner (line 131) | func (m *muxer) runInner() error {
method createInstance (line 227) | func (m *muxer) createInstance(strm *stream.Stream) (*muxerInstance, e...
method getInstance (line 243) | func (m *muxer) getInstance() muxerGetInstanceRes {
method APIReaderDescribe (line 256) | func (m *muxer) APIReaderDescribe() *defs.APIPathReader {
method handleRequest (line 263) | func (m *muxer) handleRequest(ctx *gin.Context) {
method apiItem (line 280) | func (m *muxer) apiItem() *defs.APIHLSMuxer {
FILE: internal/servers/hls/muxer_instance.go
type muxerInstance (line 17) | type muxerInstance struct
method initialize (line 32) | func (mi *muxerInstance) initialize() error {
method Log (line 75) | func (mi *muxerInstance) Log(level logger.Level, format string, args ....
method close (line 79) | func (mi *muxerInstance) close() {
method errorChan (line 87) | func (mi *muxerInstance) errorChan() chan error {
method handleRequest (line 91) | func (mi *muxerInstance) handleRequest(w http.ResponseWriter, r *http....
FILE: internal/servers/hls/server.go
function interfaceIsEmpty (line 20) | func interfaceIsEmpty(i any) bool {
type serverGetMuxerRes (line 24) | type serverGetMuxerRes struct
type serverGetMuxerReq (line 29) | type serverGetMuxerReq struct
type serverAPIMuxersListRes (line 37) | type serverAPIMuxersListRes struct
type serverAPIMuxersListReq (line 42) | type serverAPIMuxersListReq struct
type serverAPIMuxersGetRes (line 46) | type serverAPIMuxersGetRes struct
type serverAPIMuxersGetReq (line 51) | type serverAPIMuxersGetReq struct
type serverMetrics (line 56) | type serverMetrics interface
type serverPathManager (line 60) | type serverPathManager interface
type serverParent (line 66) | type serverParent interface
type Server (line 71) | type Server struct
method Initialize (line 109) | func (s *Server) Initialize() error {
method Log (line 154) | func (s *Server) Log(level logger.Level, format string, args ...any) {
method Close (line 159) | func (s *Server) Close() {
method run (line 170) | func (s *Server) run() {
method createMuxer (line 255) | func (s *Server) createMuxer(pathName string, remoteAddr string, query...
method closeMuxer (line 278) | func (s *Server) closeMuxer(c *muxer) {
method getMuxer (line 285) | func (s *Server) getMuxer(req serverGetMuxerReq) (*muxer, error) {
method PathReady (line 299) | func (s *Server) PathReady(pa defs.Path) {
method PathNotReady (line 307) | func (s *Server) PathNotReady(pa defs.Path) {
method APIMuxersList (line 315) | func (s *Server) APIMuxersList() (*defs.APIHLSMuxerList, error) {
method APIMuxersGet (line 331) | func (s *Server) APIMuxersGet(name string) (*defs.APIHLSMuxer, error) {
FILE: internal/servers/hls/server_test.go
type dummyPathManager (line 27) | type dummyPathManager struct
method SetHLSServer (line 33) | func (pm *dummyPathManager) SetHLSServer(*Server) []defs.Path {
method FindPathConf (line 40) | func (pm *dummyPathManager) FindPathConf(req defs.PathFindPathConfReq)...
method AddReader (line 44) | func (pm *dummyPathManager) AddReader(req defs.PathAddReaderReq) (*def...
type dummyPath (line 48) | type dummyPath struct
method Name (line 50) | func (pa *dummyPath) Name() string {
method SafeConf (line 54) | func (pa *dummyPath) SafeConf() *conf.Path {
method ExternalCmdEnv (line 58) | func (pa *dummyPath) ExternalCmdEnv() externalcmd.Environment {
method RemovePublisher (line 62) | func (pa *dummyPath) RemovePublisher(_ defs.PathRemovePublisherReq) {
method RemoveReader (line 65) | func (pa *dummyPath) RemoveReader(_ defs.PathRemoveReaderReq) {
function TestServerPreflightRequest (line 68) | func TestServerPreflightRequest(t *testing.T) {
function TestServerNotFound (line 106) | func TestServerNotFound(t *testing.T) {
function TestServerRead (line 176) | func TestServerRead(t *testing.T) {
function TestServerDirectory (line 410) | func TestServerDirectory(t *testing.T) {
function TestServerDynamicAlwaysRemux (line 469) | func TestServerDynamicAlwaysRemux(t *testing.T) {
function TestAuthError (line 523) | func TestAuthError(t *testing.T) {
FILE: internal/servers/rtmp/conn.go
type conn (line 26) | type conn struct
method initialize (line 54) | func (c *conn) initialize() {
method Close (line 67) | func (c *conn) Close() {
method remoteAddr (line 71) | func (c *conn) remoteAddr() net.Addr {
method Log (line 76) | func (c *conn) Log(level logger.Level, format string, args ...any) {
method ip (line 80) | func (c *conn) ip() net.IP {
method run (line 84) | func (c *conn) run() { //nolint:dupl
method runInner (line 107) | func (c *conn) runInner() error {
method runReader (line 125) | func (c *conn) runReader() error {
method runRead (line 152) | func (c *conn) runRead() error {
method runPublish (line 227) | func (c *conn) runPublish() error {
method APIReaderDescribe (line 297) | func (c *conn) APIReaderDescribe() *defs.APIPathReader {
method APISourceDescribe (line 310) | func (c *conn) APISourceDescribe() *defs.APIPathSource {
method apiItem (line 322) | func (c *conn) apiItem() *defs.APIRTMPConn {
FILE: internal/servers/rtmp/listener.go
type listener (line 8) | type listener struct
method initialize (line 14) | func (l *listener) initialize() {
method run (line 19) | func (l *listener) run() {
method runInner (line 27) | func (l *listener) runInner() error {
FILE: internal/servers/rtmp/server.go
function interfaceIsEmpty (line 28) | func interfaceIsEmpty(i any) bool {
type serverAPIConnsListRes (line 32) | type serverAPIConnsListRes struct
type serverAPIConnsListReq (line 37) | type serverAPIConnsListReq struct
type serverAPIConnsGetRes (line 41) | type serverAPIConnsGetRes struct
type serverAPIConnsGetReq (line 46) | type serverAPIConnsGetReq struct
type serverAPIConnsKickRes (line 51) | type serverAPIConnsKickRes struct
type serverAPIConnsKickReq (line 55) | type serverAPIConnsKickReq struct
type serverMetrics (line 60) | type serverMetrics interface
type serverPathManager (line 65) | type serverPathManager interface
type serverParent (line 70) | type serverParent interface
type Server (line 75) | type Server struct
method Initialize (line 109) | func (s *Server) Initialize() error {
method Log (line 172) | func (s *Server) Log(level logger.Level, format string, args ...any) {
method Close (line 183) | func (s *Server) Close() {
method run (line 202) | func (s *Server) run() {
method findConnByUUID (line 279) | func (s *Server) findConnByUUID(uuid uuid.UUID) *conn {
method newConn (line 289) | func (s *Server) newConn(conn net.Conn) {
method acceptError (line 298) | func (s *Server) acceptError(err error) {
method closeConn (line 306) | func (s *Server) closeConn(c *conn) {
method APIConnsList (line 314) | func (s *Server) APIConnsList() (*defs.APIRTMPConnList, error) {
method APIConnsGet (line 330) | func (s *Server) APIConnsGet(uuid uuid.UUID) (*defs.APIRTMPConn, error) {
method APIConnsKick (line 347) | func (s *Server) APIConnsKick(uuid uuid.UUID) error {
FILE: internal/servers/rtmp/server_test.go
type dummyPath (line 23) | type dummyPath struct
method Name (line 25) | func (p *dummyPath) Name() string {
method SafeConf (line 29) | func (p *dummyPath) SafeConf() *conf.Path {
method ExternalCmdEnv (line 33) | func (p *dummyPath) ExternalCmdEnv() externalcmd.Environment {
method RemovePublisher (line 37) | func (p *dummyPath) RemovePublisher(_ defs.PathRemovePublisherReq) {
method RemoveReader (line 40) | func (p *dummyPath) RemoveReader(_ defs.PathRemoveReaderReq) {
function TestServerPublish (line 43) | func TestServerPublish(t *testing.T) {
function TestServerRead (line 218) | func TestServerRead(t *testing.T) {
FILE: internal/servers/rtsp/conn.go
function absoluteURL (line 26) | func absoluteURL(req *base.Request, v string) string {
function tunnelLabel (line 39) | func tunnelLabel(t gortsplib.Tunnel) string {
type connParent (line 51) | type connParent interface
type conn (line 56) | type conn struct
method initialize (line 75) | func (c *conn) initialize() {
method Log (line 101) | func (c *conn) Log(level logger.Level, format string, args ...any) {
method Conn (line 106) | func (c *conn) Conn() *gortsplib.ServerConn {
method remoteAddr (line 110) | func (c *conn) remoteAddr() net.Addr {
method ip (line 114) | func (c *conn) ip() net.IP {
method onClose (line 119) | func (c *conn) onClose(err error) {
method onRequest (line 126) | func (c *conn) onRequest(req *base.Request) {
method OnResponse (line 131) | func (c *conn) OnResponse(res *base.Response) {
method onDescribe (line 136) | func (c *conn) onDescribe(ctx *gortsplib.ServerHandlerOnDescribeCtx,
method handleAuthError (line 206) | func (c *conn) handleAuthError(err *auth.Error) (*base.Response, error) {
method apiItem (line 221) | func (c *conn) apiItem() *defs.APIRTSPConn {
FILE: internal/servers/rtsp/mpegts_demuxer.go
type mpegtsDemuxer (line 21) | type mpegtsDemuxer struct
method initialize (line 34) | func (d *mpegtsDemuxer) initialize() error {
method close (line 64) | func (d *mpegtsDemuxer) close() {
method run (line 68) | func (d *mpegtsDemuxer) run(pr *io.PipeReader) {
method doRun (line 76) | func (d *mpegtsDemuxer) doRun(pr *io.PipeReader) error {
FILE: internal/servers/rtsp/server.go
function interfaceIsEmpty (line 36) | func interfaceIsEmpty(i any) bool {
function printAddresses (line 40) | func printAddresses(srv *gortsplib.Server) string {
type serverMetrics (line 74) | type serverMetrics interface
type serverPathManager (line 79) | type serverPathManager interface
type serverParent (line 86) | type serverParent interface
type Server (line 91) | type Server struct
method Initialize (line 129) | func (s *Server) Initialize() error {
method Log (line 204) | func (s *Server) Log(level logger.Level, format string, args ...any) {
method Close (line 215) | func (s *Server) Close() {
method run (line 234) | func (s *Server) run() {
method OnConnOpen (line 258) | func (s *Server) OnConnOpen(ctx *gortsplib.ServerHandlerOnConnOpenCtx) {
method OnConnClose (line 282) | func (s *Server) OnConnClose(ctx *gortsplib.ServerHandlerOnConnCloseCt...
method OnRequest (line 291) | func (s *Server) OnRequest(sc *gortsplib.ServerConn, req *base.Request) {
method OnResponse (line 297) | func (s *Server) OnResponse(sc *gortsplib.ServerConn, res *base.Respon...
method OnSessionOpen (line 303) | func (s *Server) OnSessionOpen(ctx *gortsplib.ServerHandlerOnSessionOp...
method OnSessionClose (line 322) | func (s *Server) OnSessionClose(ctx *gortsplib.ServerHandlerOnSessionC...
method OnDescribe (line 334) | func (s *Server) OnDescribe(ctx *gortsplib.ServerHandlerOnDescribeCtx,
method OnAnnounce (line 341) | func (s *Server) OnAnnounce(ctx *gortsplib.ServerHandlerOnAnnounceCtx)...
method OnSetup (line 348) | func (s *Server) OnSetup(ctx *gortsplib.ServerHandlerOnSetupCtx) (*bas...
method OnPlay (line 355) | func (s *Server) OnPlay(ctx *gortsplib.ServerHandlerOnPlayCtx) (*base....
method OnRecord (line 361) | func (s *Server) OnRecord(ctx *gortsplib.ServerHandlerOnRecordCtx) (*b...
method OnPause (line 367) | func (s *Server) OnPause(ctx *gortsplib.ServerHandlerOnPauseCtx) (*bas...
method OnPacketsLost (line 373) | func (s *Server) OnPacketsLost(ctx *gortsplib.ServerHandlerOnPacketsLo...
method OnDecodeError (line 379) | func (s *Server) OnDecodeError(ctx *gortsplib.ServerHandlerOnDecodeErr...
method OnStreamWriteError (line 385) | func (s *Server) OnStreamWriteError(ctx *gortsplib.ServerHandlerOnStre...
method findConnByUUID (line 390) | func (s *Server) findConnByUUID(uuid uuid.UUID) *conn {
method findSessionByUUID (line 399) | func (s *Server) findSessionByUUID(uuid uuid.UUID) (*gortsplib.ServerS...
method getConnByRConnUnsafe (line 408) | func (s *Server) getConnByRConnUnsafe(rconn *gortsplib.ServerConn) *co...
method getSessionByRSessionUnsafe (line 412) | func (s *Server) getSessionByRSessionUnsafe(rsession *gortsplib.Server...
method APIConnsList (line 417) | func (s *Server) APIConnsList() (*defs.APIRTSPConnsList, error) {
method APIConnsGet (line 443) | func (s *Server) APIConnsGet(uuid uuid.UUID) (*defs.APIRTSPConn, error) {
method APISessionsList (line 462) | func (s *Server) APISessionsList() (*defs.APIRTSPSessionList, error) {
method APISessionsGet (line 488) | func (s *Server) APISessionsGet(uuid uuid.UUID) (*defs.APIRTSPSession,...
method APISessionsKick (line 507) | func (s *Server) APISessionsKick(uuid uuid.UUID) error {
FILE: internal/servers/rtsp/server_test.go
function ptrOf (line 30) | func ptrOf[T any](v T) *T {
type dummyPath (line 36) | type dummyPath struct
method Name (line 38) | func (p *dummyPath) Name() string {
method SafeConf (line 42) | func (p *dummyPath) SafeConf() *conf.Path {
method ExternalCmdEnv (line 46) | func (p *dummyPath) ExternalCmdEnv() externalcmd.Environment {
method RemovePublisher (line 50) | func (p *dummyPath) RemovePublisher(_ defs.PathRemovePublisherReq) {
method RemoveReader (line 53) | func (p *dummyPath) RemoveReader(_ defs.PathRemoveReaderReq) {
function TestServerPublish (line 56) | func TestServerPublish(t *testing.T) {
function TestServerPublishMPEGTS (line 213) | func TestServerPublishMPEGTS(t *testing.T) {
function TestServerRead (line 360) | func TestServerRead(t *testing.T) {
function TestServerRedirect (line 537) | func TestServerRedirect(t *testing.T) {
function TestAuthError (line 621) | func TestAuthError(t *testing.T) {
FILE: internal/servers/rtsp/session.go
function profileLabel (line 32) | func profileLabel(p headers.TransportProfile) string {
function findSingleMPEGTSFormat (line 42) | func findSingleMPEGTSFormat(desc *description.Session) (*description.Med...
type sessionParent (line 55) | type sessionParent interface
type session (line 60) | type session struct
method initialize (line 85) | func (s *session) initialize() {
method Close (line 134) | func (s *session) Close() {
method remoteAddr (line 138) | func (s *session) remoteAddr() net.Addr {
method Log (line 143) | func (s *session) Log(level logger.Level, format string, args ...any) {
method onClose (line 149) | func (s *session) onClose(err error) {
method onAnnounce (line 180) | func (s *session) onAnnounce(c *conn, ctx *gortsplib.ServerHandlerOnAn...
method rtspStream (line 231) | func (s *session) rtspStream() *gortsplib.ServerStream {
method onSetup (line 239) | func (s *session) onSetup(c *conn, ctx *gortsplib.ServerHandlerOnSetup...
method onPlay (line 326) | func (s *session) onPlay(_ *gortsplib.ServerHandlerOnPlayCtx) (*base.R...
method onRecord (line 352) | func (s *session) onRecord(_ *gortsplib.ServerHandlerOnRecordCtx) (*ba...
method onPause (line 416) | func (s *session) onPause(_ *gortsplib.ServerHandlerOnPauseCtx) (*base...
method APIReaderDescribe (line 439) | func (s *session) APIReaderDescribe() *defs.APIPathReader {
method APISourceDescribe (line 452) | func (s *session) APISourceDescribe() *defs.APIPathSource {
method onPacketsLost (line 465) | func (s *session) onPacketsLost(ctx *gortsplib.ServerHandlerOnPacketsL...
method onDecodeError (line 470) | func (s *session) onDecodeError(ctx *gortsplib.ServerHandlerOnDecodeEr...
method onStreamWriteError (line 475) | func (s *session) onStreamWriteError(_ *gortsplib.ServerHandlerOnStrea...
method apiItem (line 480) | func (s *session) apiItem() *defs.APIRTSPSession {
FILE: internal/servers/srt/conn.go
function srtCheckPassphrase (line 27) | func srtCheckPassphrase(connReq srt.ConnRequest, passphrase string) error {
type conn (line 44) | type conn struct
method initialize (line 72) | func (c *conn) initialize() {
method Close (line 85) | func (c *conn) Close() {
method Log (line 90) | func (c *conn) Log(level logger.Level, format string, args ...any) {
method ip (line 94) | func (c *conn) ip() net.IP {
method run (line 98) | func (c *conn) run() { //nolint:dupl
method runInner (line 121) | func (c *conn) runInner() error {
method runPublish (line 135) | func (c *conn) runPublish(streamID *streamID) error {
method runPublishReader (line 194) | func (c *conn) runPublishReader(sconn srt.Conn, streamID *streamID, pa...
method runRead (line 262) | func (c *conn) runRead(streamID *streamID) error {
method APIReaderDescribe (line 353) | func (c *conn) APIReaderDescribe() *defs.APIPathReader {
method APISourceDescribe (line 361) | func (c *conn) APISourceDescribe() *defs.APIPathSource {
method apiItem (line 368) | func (c *conn) apiItem() *defs.APISRTConn {
FILE: internal/servers/srt/listener.go
type listener (line 9) | type listener struct
method initialize (line 15) | func (l *listener) initialize() {
method run (line 20) | func (l *listener) run() {
method runInner (line 28) | func (l *listener) runInner() error {
FILE: internal/servers/srt/server.go
function interfaceIsEmpty (line 25) | func interfaceIsEmpty(i any) bool {
function srtMaxPayloadSize (line 29) | func srtMaxPayloadSize(u int) int {
type serverAPIConnsListRes (line 33) | type serverAPIConnsListRes struct
type serverAPIConnsListReq (line 38) | type serverAPIConnsListReq struct
type serverAPIConnsGetRes (line 42) | type serverAPIConnsGetRes struct
type serverAPIConnsGetReq (line 47) | type serverAPIConnsGetReq struct
type serverAPIConnsKickRes (line 52) | type serverAPIConnsKickRes struct
type serverAPIConnsKickReq (line 56) | type serverAPIConnsKickReq struct
type serverMetrics (line 61) | type serverMetrics interface
type serverPathManager (line 65) | type serverPathManager interface
type serverParent (line 71) | type serverParent interface
type Server (line 76) | type Server struct
method Initialize (line 106) | func (s *Server) Initialize() error {
method Log (line 148) | func (s *Server) Log(level logger.Level, format string, args ...any) {
method Close (line 153) | func (s *Server) Close() {
method run (line 164) | func (s *Server) run() {
method findConnByUUID (line 241) | func (s *Server) findConnByUUID(uuid uuid.UUID) *conn {
method newConnRequest (line 251) | func (s *Server) newConnRequest(connReq srt.ConnRequest) {
method acceptError (line 260) | func (s *Server) acceptError(err error) {
method closeConn (line 268) | func (s *Server) closeConn(c *conn) {
method APIConnsList (line 276) | func (s *Server) APIConnsList() (*defs.APISRTConnList, error) {
method APIConnsGet (line 292) | func (s *Server) APIConnsGet(uuid uuid.UUID) (*defs.APISRTConn, error) {
method APIConnsKick (line 309) | func (s *Server) APIConnsKick(uuid uuid.UUID) error {
FILE: internal/servers/srt/server_test.go
type dummyPath (line 21) | type dummyPath struct
method Name (line 23) | func (p *dummyPath) Name() string {
method SafeConf (line 27) | func (p *dummyPath) SafeConf() *conf.Path {
method ExternalCmdEnv (line 31) | func (p *dummyPath) ExternalCmdEnv() externalcmd.Environment {
method RemovePublisher (line 35) | func (p *dummyPath) RemovePublisher(_ defs.PathRemovePublisherReq) {
method RemoveReader (line 38) | func (p *dummyPath) RemoveReader(_ defs.PathRemoveReaderReq) {
function TestServerPublish (line 41) | func TestServerPublish(t *testing.T) {
function TestServerRead (line 252) | func TestServerRead(t *testing.T) {
FILE: internal/servers/srt/streamid.go
type streamIDMode (line 8) | type streamIDMode
constant streamIDModeRead (line 11) | streamIDModeRead streamIDMode = iota
constant streamIDModePublish (line 12) | streamIDModePublish
type streamID (line 15) | type streamID struct
method unmarshal (line 23) | func (s *streamID) unmarshal(raw string) error {
FILE: internal/servers/srt/streamid_test.go
function TestStreamIDUnmarshal (line 9) | func TestStreamIDUnmarshal(t *testing.T) {
FILE: internal/servers/webrtc/http_server.go
function mergePathAndQuery (line 42) | func mergePathAndQuery(path string, rawQuery string) string {
function writeError (line 50) | func writeError(ctx *gin.Context, statusCode int, err error) {
function sessionLocation (line 57) | func sessionLocation(publish bool, path string, rawQuery string, secret ...
type httpServer (line 75) | type httpServer struct
method initialize (line 91) | func (s *httpServer) initialize() error {
method Log (line 121) | func (s *httpServer) Log(level logger.Level, format string, args ...an...
method close (line 125) | func (s *httpServer) close() {
method checkAuthOutsideSession (line 129) | func (s *httpServer) checkAuthOutsideSession(ctx *gin.Context, pathNam...
method onWHIPOptions (line 168) | func (s *httpServer) onWHIPOptions(ctx *gin.Context, pathName string, ...
method onWHIPPost (line 186) | func (s *httpServer) onWHIPPost(ctx *gin.Context, pathName string, pub...
method onWHIPPatch (line 252) | func (s *httpServer) onWHIPPatch(ctx *gin.Context, pathName string, ra...
method onWHIPDelete (line 295) | func (s *httpServer) onWHIPDelete(ctx *gin.Context, pathName string, r...
method onPage (line 320) | func (s *httpServer) onPage(ctx *gin.Context, pathName string, publish...
method middlewarePreflightRequests (line 340) | func (s *httpServer) middlewarePreflightRequests(ctx *gin.Context) {
method onRequest (line 350) | func (s *httpServer) onRequest(ctx *gin.Context) {
FILE: internal/servers/webrtc/publisher.js
class MediaMTXWebRTCPublisher (line 30) | class MediaMTXWebRTCPublisher {
method constructor (line 35) | constructor(conf) {
method #unquoteCredential (line 62) | static #unquoteCredential(v) {
method #linkToIceServers (line 66) | static #linkToIceServers(links) {
method #parseOffer (line 83) | static #parseOffer(offer) {
method #generateSdpFragment (line 103) | static #generateSdpFragment(od, candidates) {
method #setCodec (line 133) | static #setCodec(section, codec) {
method #setVideoBitrate (line 172) | static #setVideoBitrate(section, bitrate) {
method #setAudioBitrate (line 185) | static #setAudioBitrate(section, bitrate, voice) {
method #editOffer (line 215) | static #editOffer(sdp, videoCodec, audioCodec, audioBitrate, audioVoic...
method #editAnswer (line 229) | static #editAnswer(sdp, videoBitrate) {
method #start (line 241) | #start() {
method #handleError (line 251) | #handleError(err) {
method #authHeader (line 282) | #authHeader() {
method #requestICEServers (line 293) | #requestICEServers() {
method #setupPeerConnection (line 303) | #setupPeerConnection(iceServers) {
method #sendOffer (line 330) | #sendOffer(offer) {
method #setAnswer (line 366) | #setAnswer(answer) {
method #onLocalCandidate (line 389) | #onLocalCandidate(evt) {
method #sendLocalCandidates (line 403) | #sendLocalCandidates(candidates) {
method #onConnectionState (line 427) | #onConnectionState() {
FILE: internal/servers/webrtc/reader.js
class MediaMTXWebRTCReader (line 31) | class MediaMTXWebRTCReader {
method constructor (line 36) | constructor(conf) {
method close (line 51) | close() {
method #supportsNonAdvertisedCodec (line 63) | static #supportsNonAdvertisedCodec(codec, fmtp) {
method #unquoteCredential (line 126) | static #unquoteCredential(v) {
method #linkToIceServers (line 130) | static #linkToIceServers(links) {
method #parseOffer (line 147) | static #parseOffer(sdp) {
method #reservePayloadType (line 167) | static #reservePayloadType(payloadTypes) {
method #enableStereoPcmau (line 180) | static #enableStereoPcmau(payloadTypes, section) {
method #enableMultichannelOpus (line 196) | static #enableMultichannelOpus(payloadTypes, section) {
method #enableL16 (line 238) | static #enableL16(payloadTypes, section) {
method #enableStereoOpus (line 259) | static #enableStereoOpus(section) {
method #editOffer (line 288) | static #editOffer(sdp, nonAdvertisedCodecs) {
method #generateSdpFragment (line 316) | static #generateSdpFragment(od, candidates) {
method #handleError (line 346) | #handleError(err) {
method #getNonAdvertisedCodecs (line 383) | #getNonAdvertisedCodecs() {
method #start (line 405) | #start() {
method #authHeader (line 415) | #authHeader() {
method #requestICEServers (line 426) | #requestICEServers() {
method #setupPeerConnection (line 436) | #setupPeerConnection(iceServers) {
method #sendOffer (line 469) | #sendOffer(offer) {
method #setAnswer (line 500) | #setAnswer(answer) {
method #onLocalCandidate (line 521) | #onLocalCandidate(evt) {
method #sendLocalCandidates (line 535) | #sendLocalCandidates(candidates) {
method #onConnectionState (line 559) | #onConnectionState() {
method #onTrack (line 575) | #onTrack(evt) {
method #onDataChannel (line 581) | #onDataChannel(evt) {
FILE: internal/servers/webrtc/server.go
constant webrtcTurnSecretExpiration (line 35) | webrtcTurnSecretExpiration = 24 * time.Hour
function interfaceIsEmpty (line 41) | func interfaceIsEmpty(i any) bool {
type nilWriter (line 45) | type nilWriter struct
method Write (line 47) | func (nilWriter) Write(p []byte) (int, error) {
function randInt63 (line 53) | func randInt63() (int64, error) {
function randInt63n (line 65) | func randInt63n(n int64) (int64, error) {
function randomTurnUser (line 91) | func randomTurnUser() (string, error) {
type serverAPISessionsListRes (line 106) | type serverAPISessionsListRes struct
type serverAPISessionsListReq (line 111) | type serverAPISessionsListReq struct
type serverAPISessionsGetRes (line 115) | type serverAPISessionsGetRes struct
type serverAPISessionsGetReq (line 120) | type serverAPISessionsGetReq struct
type serverAPISessionsKickRes (line 125) | type serverAPISessionsKickRes struct
type serverAPISessionsKickReq (line 129) | type serverAPISessionsKickReq struct
type webRTCNewSessionRes (line 134) | type webRTCNewSessionRes struct
type webRTCNewSessionReq (line 141) | type webRTCNewSessionReq struct
type webRTCAddSessionCandidatesRes (line 150) | type webRTCAddSessionCandidatesRes struct
type webRTCAddSessionCandidatesReq (line 155) | type webRTCAddSessionCandidatesReq struct
type webRTCDeleteSessionRes (line 162) | type webRTCDeleteSessionRes struct
type webRTCDeleteSessionReq (line 166) | type webRTCDeleteSessionReq struct
type serverMetrics (line 172) | type serverMetrics interface
type serverPathManager (line 176) | type serverPathManager interface
type serverParent (line 182) | type serverParent interface
type Server (line 187) | type Server struct
method Initialize (line 236) | func (s *Server) Initialize() error {
method Log (line 328) | func (s *Server) Log(level logger.Level, format string, args ...any) {
method Close (line 333) | func (s *Server) Close() {
method run (line 344) | func (s *Server) run() {
method findSessionByUUID (line 458) | func (s *Server) findSessionByUUID(uuid uuid.UUID) *session {
method generateICEServers (line 467) | func (s *Server) generateICEServers(clientConfig bool) ([]pwebrtc.ICES...
method newSession (line 500) | func (s *Server) newSession(req webRTCNewSessionReq) webRTCNewSessionR...
method closeSession (line 518) | func (s *Server) closeSession(sx *session) {
method addSessionCandidates (line 526) | func (s *Server) addSessionCandidates(
method deleteSession (line 545) | func (s *Server) deleteSession(req webRTCDeleteSessionReq) error {
method APISessionsList (line 558) | func (s *Server) APISessionsList() (*defs.APIWebRTCSessionList, error) {
method APISessionsGet (line 574) | func (s *Server) APISessionsGet(uuid uuid.UUID) (*defs.APIWebRTCSessio...
method APISessionsKick (line 591) | func (s *Server) APISessionsKick(uuid uuid.UUID) error {
FILE: internal/servers/webrtc/server_test.go
function ptrOf (line 33) | func ptrOf[T any](v T) *T {
function checkClose (line 39) | func checkClose(t *testing.T, closeFunc func() error) {
type dummyPath (line 43) | type dummyPath struct
method Name (line 45) | func (p *dummyPath) Name() string {
method SafeConf (line 49) | func (p *dummyPath) SafeConf() *conf.Path {
method ExternalCmdEnv (line 53) | func (p *dummyPath) ExternalCmdEnv() externalcmd.Environment {
method RemovePublisher (line 57) | func (p *dummyPath) RemovePublisher(_ defs.PathRemovePublisherReq) {
method RemoveReader (line 60) | func (p *dummyPath) RemoveReader(_ defs.PathRemoveReaderReq) {
function initializeTestServer (line 63) | func initializeTestServer(t *testing.T) *Server {
function TestServerStaticPages (line 94) | func TestServerStaticPages(t *testing.T) {
function TestPreflightRequest (line 116) | func TestPreflightRequest(t *testing.T) {
function TestServerOptionsICEServer (line 145) | func TestServerOptionsICEServer(t *testing.T) {
function TestServerPublish (line 201) | func TestServerPublish(t *testing.T) {
function TestServerRead (line 360) | func TestServerRead(t *testing.T) {
function TestServerReadNotFound (line 656) | func TestServerReadNotFound(t *testing.T) {
function TestServerPatchNotFound (line 714) | func TestServerPatchNotFound(t *testing.T) {
function TestServerDeleteNotFound (line 751) | func TestServerDeleteNotFound(t *testing.T) {
function TestICEServerNoClientOnly (line 770) | func TestICEServerNoClientOnly(t *testing.T) {
function TestICEServerClientOnly (line 788) | func TestICEServerClientOnly(t *testing.T) {
function TestAuthError (line 807) | func TestAuthError(t *testing.T) {
FILE: internal/servers/webrtc/session.go
function whipOffer (line 30) | func whipOffer(body []byte) *pwebrtc.SessionDescription {
type sessionParent (line 37) | type sessionParent interface
type session (line 43) | type session struct
method initialize (line 74) | func (s *session) initialize() {
method Log (line 93) | func (s *session) Log(level logger.Level, format string, args ...any) {
method Close (line 98) | func (s *session) Close() {
method run (line 102) | func (s *session) run() {
method runInner (line 114) | func (s *session) runInner() error {
method runInner2 (line 133) | func (s *session) runInner2() (int, error) {
method runPublish (line 140) | func (s *session) runPublish() (int, error) {
method runRead (line 279) | func (s *session) runRead() (int, error) {
method writeAnswer (line 407) | func (s *session) writeAnswer(answer *pwebrtc.SessionDescription) {
method readRemoteCandidates (line 414) | func (s *session) readRemoteCandidates(pc *webrtc.PeerConnection) {
method new (line 433) | func (s *session) new(req webRTCNewSessionReq) webRTCNewSessionRes {
method addCandidates (line 444) | func (s *session) addCandidates(
method APIReaderDescribe (line 457) | func (s *session) APIReaderDescribe() *defs.APIPathReader {
method APISourceDescribe (line 465) | func (s *session) APISourceDescribe() *defs.APIPathSource {
method apiItem (line 472) | func (s *session) apiItem() *defs.APIWebRTCSession {
FILE: internal/staticsources/handler.go
constant retryPause (line 25) | retryPause = 5 * time.Second
function emptyTimer (line 28) | func emptyTimer() *time.Timer {
function resolveSource (line 34) | func resolveSource(s string, matches []string, query string) string {
type staticSource (line 46) | type staticSource interface
type handlerPathManager (line 52) | type handlerPathManager interface
type handlerParent (line 56) | type handlerParent interface
type Handler (line 63) | type Handler struct
method Initialize (line 92) | func (s *Handler) Initialize() {
method Close (line 177) | func (s *Handler) Close(reason string) {
method Start (line 182) | func (s *Handler) Start(onDemand bool, query string) {
method Stop (line 204) | func (s *Handler) Stop(reason string) {
method Log (line 220) | func (s *Handler) Log(level logger.Level, format string, args ...any) {
method run (line 224) | func (s *Handler) run() {
method ReloadConf (line 293) | func (s *Handler) ReloadConf(newConf *conf.Path) {
method APISourceDescribe (line 309) | func (s *Handler) APISourceDescribe() *defs.APIPathSource {
method SetReady (line 314) | func (s *Handler) SetReady(req defs.PathSourceStaticSetReadyReq) defs....
method SetNotReady (line 326) | func (s *Handler) SetNotReady(req defs.PathSourceStaticSetNotReadyReq) {
method AddReader (line 336) | func (s *Handler) AddReader(req defs.PathAddReaderReq) (*defs.PathAddR...
FILE: internal/staticsources/hls/source.go
type parent (line 24) | type parent interface
type Source (line 31) | type Source struct
method Log (line 38) | func (s *Source) Log(level logger.Level, format string, args ...any) {
method Run (line 43) | func (s *Source) Run(params defs.StaticSourceRunParams) error {
method APISourceDescribe (line 158) | func (*Source) APISourceDescribe() *defs.APIPathSource {
FILE: internal/staticsources/hls/source_test.go
function TestSource (line 19) | func TestSource(t *testing.T) {
function TestSourceCookie (line 124) | func TestSourceCookie(t *testing.T) {
FILE: internal/staticsources/mpegts/source.go
type parent (line 23) | type parent interface
type Source (line 30) | type Source struct
method Log (line 38) | func (s *Source) Log(level logger.Level, format string, args ...any) {
method Run (line 43) | func (s *Source) Run(params defs.StaticSourceRunParams) error {
method runReader (line 129) | func (s *Source) runReader(nc net.Conn) error {
method APISourceDescribe (line 184) | func (*Source) APISourceDescribe() *defs.APIPathSource {
FILE: internal/staticsources/mpegts/source_test.go
function multicastCapableInterface (line 21) | func multicastCapableInterface(t *testing.T) string {
function TestSourceUDP (line 35) | func TestSourceUDP(t *testing.T) {
function TestSourceUnixSocket (line 150) | func TestSourceUnixSocket(t *testing.T) {
FILE: internal/staticsources/rpicamera/camera_arm_.go
constant libraryToCheckArchitecture (line 23) | libraryToCheckArchitecture = "libc.so.6"
constant dumpPrefix (line 24) | dumpPrefix = "/dev/shm/mediamtx-rpicamera-"
constant executableName (line 25) | executableName = "mtxrpicam"
function ntpTime (line 34) | func ntpTime() syscall.Timespec {
function monotonicTime (line 40) | func monotonicTime() syscall.Timespec {
function multiplyAndDivide (line 46) | func multiplyAndDivide(v, m, d int64) int64 {
function getArchitecture (line 52) | func getArchitecture(libPath string) (bool, error) {
function checkArchitecture (line 68) | func checkArchitecture() error {
function dumpEmbedFSRecursive (line 101) | func dumpEmbedFSRecursive(src string, dest string) error {
function dumpComponent (line 134) | func dumpComponent() error {
function freeComponent (line 178) | func freeComponent() {
type camera (line 189) | type camera struct
method initialize (line 203) | func (c *camera) initialize() error {
method close (line 258) | func (c *camera) close() {
method run (line 264) | func (c *camera) run() {
method runInner (line 269) | func (c *camera) runInner() error {
method runReader (line 315) | func (c *camera) runReader() error {
method reloadParams (line 391) | func (c *camera) reloadParams(params params) {
method wait (line 395) | func (c *camera) wait() error {
FILE: internal/staticsources/rpicamera/camera_other.go
type camera (line 10) | type camera struct
method initialize (line 16) | func (c *camera) initialize() error {
method close (line 20) | func (c *camera) close() {
method reloadParams (line 23) | func (c *camera) reloadParams(_ params) {
method wait (line 26) | func (c *camera) wait() error {
FILE: internal/staticsources/rpicamera/mtxrpicamdownloader/main.go
function dumpTar (line 19) | func dumpTar(src io.Reader) error {
function doSingle (line 62) | func doSingle(version string, f string) error {
function do (line 101) | func do() error {
function main (line 121) | func main() {
FILE: internal/staticsources/rpicamera/params.go
type params (line 3) | type params struct
FILE: internal/staticsources/rpicamera/params_serialize.go
method serialize (line 12) | func (p params) serialize() []byte {
FILE: internal/staticsources/rpicamera/pipe.go
function syscallReadAll (line 9) | func syscallReadAll(fd int, buf []byte) error {
type pipe (line 28) | type pipe struct
method close (line 46) | func (p *pipe) close() {
method read (line 51) | func (p *pipe) read() ([]byte, error) {
method write (line 69) | func (p *pipe) write(byts []byte) error {
function newPipe (line 33) | func newPipe() (*pipe, error) {
FILE: internal/staticsources/rpicamera/source.go
constant pauseBetweenErrors (line 24) | pauseBetweenErrors = 1 * time.Second
function paramsFromConf (line 27) | func paramsFromConf(logLevel conf.LogLevel, cnf *conf.Path) params {
type secondaryReader (line 85) | type secondaryReader struct
method Close (line 91) | func (r *secondaryReader) Close() {
method APIReaderDescribe (line 96) | func (*secondaryReader) APIReaderDescribe() *defs.APIPathReader {
type parent (line 103) | type parent interface
type Source (line 111) | type Source struct
method Log (line 118) | func (s *Source) Log(level logger.Level, format string, args ...any) {
method Run (line 123) | func (s *Source) Run(params defs.StaticSourceRunParams) error {
method runPrimary (line 130) | func (s *Source) runPrimary(params defs.StaticSourceRunParams) error {
method runSecondary (line 269) | func (s *Source) runSecondary(params defs.StaticSourceRunParams) error {
method waitForPrimary (line 331) | func (s *Source) waitForPrimary(
method APISourceDescribe (line 362) | func (*Source) APISourceDescribe() *defs.APIPathSource {
FILE: internal/staticsources/rtmp/source.go
type parent (line 23) | type parent interface
type Source (line 30) | type Source struct
method Log (line 38) | func (s *Source) Log(level logger.Level, format string, args ...any) {
method Run (line 43) | func (s *Source) Run(params defs.StaticSourceRunParams) error {
method runReader (line 105) | func (s *Source) runReader(conn *gortmplib.Client) error {
method APISourceDescribe (line 153) | func (*Source) APISourceDescribe() *defs.APIPathSource {
FILE: internal/staticsources/rtmp/source_test.go
function TestSource (line 20) | func TestSource(t *testing.T) {
FILE: internal/staticsources/rtp/format.go
type rtpFormat (line 11) | type rtpFormat struct
method initialize (line 17) | func (f *rtpFormat) initialize() {
FILE: internal/staticsources/rtp/media.go
type rtpMedia (line 5) | type rtpMedia struct
FILE: internal/staticsources/rtp/source.go
type parent (line 26) | type parent interface
type Source (line 33) | type Source struct
method Log (line 41) | func (s *Source) Log(level logger.Level, format string, args ...any) {
method Run (line 46) | func (s *Source) Run(params defs.StaticSourceRunParams) error {
method runReader (line 144) | func (s *Source) runReader(desc *description.Session, nc net.Conn) err...
method APISourceDescribe (line 258) | func (*Source) APISourceDescribe() *defs.APIPathSource {
FILE: internal/staticsources/rtp/source_test.go
function multicastCapableInterface (line 19) | func multicastCapableInterface(t *testing.T) string {
function TestSourceUDP (line 33) | func TestSourceUDP(t *testing.T) {
function TestSourceUnixSocket (line 152) | func TestSourceUnixSocket(t *testing.T) {
FILE: internal/staticsources/rtsp/source.go
function createRangeHeader (line 26) | func createRangeHeader(cnf *conf.Path) (*headers.Range, error) {
type parent (line 71) | type parent interface
type Source (line 78) | type Source struct
method Log (line 88) | func (s *Source) Log(level logger.Level, format string, args ...any) {
method Run (line 93) | func (s *Source) Run(params defs.StaticSourceRunParams) error {
method runInner (line 223) | func (s *Source) runInner(c *gortsplib.Client, u *base.URL, pathConf *...
method APISourceDescribe (line 287) | func (*Source) APISourceDescribe() *defs.APIPathSource {
FILE: internal/staticsources/rtsp/source_test.go
function ptrOf (line 23) | func ptrOf[T any](v T) *T {
type testServer (line 29) | type testServer struct
method OnDescribe (line 35) | func (sh *testServer) OnDescribe(ctx *gortsplib.ServerHandlerOnDescrib...
method OnSetup (line 40) | func (sh *testServer) OnSetup(ctx *gortsplib.ServerHandlerOnSetupCtx) ...
method OnPlay (line 44) | func (sh *testServer) OnPlay(ctx *gortsplib.ServerHandlerOnPlayCtx) (*...
function TestSource (line 48) | func TestSource(t *testing.T) {
function TestNoPassword (line 220) | func TestNoPassword(t *testing.T) {
function TestRange (line 322) | func TestRange(t *testing.T) {
function TestSkipBackChannel (line 438) | func TestSkipBackChannel(t *testing.T) {
function TestOnlyBackChannelsError (line 537) | func TestOnlyBackChannelsError(t *testing.T) {
FILE: internal/staticsources/srt/source.go
type parent (line 18) | type parent interface
type Source (line 25) | type Source struct
method Log (line 31) | func (s *Source) Log(level logger.Level, format string, args ...any) {
method Run (line 36) | func (s *Source) Run(params defs.StaticSourceRunParams) error {
method runReader (line 76) | func (s *Source) runReader(sconn srt.Conn) error {
method APISourceDescribe (line 131) | func (*Source) APISourceDescribe() *defs.APIPathSource {
FILE: internal/staticsources/srt/source_test.go
function TestSource (line 19) | func TestSource(t *testing.T) {
FILE: internal/staticsources/webrtc/source.go
type parent (line 24) | type parent interface
type Source (line 31) | type Source struct
method Log (line 39) | func (s *Source) Log(level logger.Level, format string, args ...any) {
method Run (line 44) | func (s *Source) Run(params defs.StaticSourceRunParams) error {
method APISourceDescribe (line 134) | func (*Source) APISourceDescribe() *defs.APIPathSource {
FILE: internal/staticsources/webrtc/source_test.go
function whipOffer (line 21) | func whipOffer(body []byte) *pwebrtc.SessionDescription {
function TestSource (line 28) | func TestSource(t *testing.T) {
FILE: internal/stream/format_updater.go
type formatUpdater (line 13) | type formatUpdater
function formatUpdaterH265 (line 15) | func formatUpdaterH265(forma format.Format, payload unit.Payload) {
function formatUpdaterH264 (line 51) | func formatUpdaterH264(forma format.Format, payload unit.Payload) {
function formatUpdaterMPEG4Video (line 81) | func formatUpdaterMPEG4Video(forma format.Format, payload unit.Payload) {
function newFormatUpdater (line 98) | func newFormatUpdater(forma format.Format) formatUpdater {
FILE: internal/stream/offline_sub_stream.go
function multiplyAndDivide2 (line 9) | func multiplyAndDivide2(v, m, d time.Duration) time.Duration {
type offlineSubStream (line 15) | type offlineSubStream struct
method initialize (line 25) | func (o *offlineSubStream) initialize() error {
method close (line 61) | func (o *offlineSubStream) close(waitLastSample bool) {
FILE: internal/stream/offline_sub_stream_track.go
type offlineSubStreamTrack (line 64) | type offlineSubStreamTrack struct
method initialize (line 75) | func (t *offlineSubStreamTrack) initialize() {
method run (line 80) | func (t *offlineSubStreamTrack) run() {
method runFile (line 248) | func (t *offlineSubStreamTrack) runFile(r io.ReadSeeker, pos int) error {
method sleep (line 349) | func (t *offlineSubStreamTrack) sleep(systemTime time.Time) bool {
FILE: internal/stream/reader.go
type OnDataFunc (line 15) | type OnDataFunc
type Reader (line 18) | type Reader struct
method OnData (line 32) | func (r *Reader) OnData(medi *description.Media, forma format.Format, ...
method Formats (line 43) | func (r *Reader) Formats() []format.Format {
method OutboundFramesDiscarded (line 69) | func (r *Reader) OutboundFramesDiscarded() uint64 {
method Error (line 75) | func (r *Reader) Error() chan error {
method start (line 79) | func (r *Reader) start() {
method stop (line 101) | func (r *Reader) stop() {
method run (line 107) | func (r *Reader) run() {
method runInner (line 112) | func (r *Reader) runInner() error {
method push (line 126) | func (r *Reader) push(cb func() error) {
FILE: internal/stream/rtp_decoder.go
type rtpDecoder (line 25) | type rtpDecoder interface
type rtpDecoderAV1 (line 29) | type rtpDecoderAV1
method decode (line 31) | func (d *rtpDecoderAV1) decode(pkt *rtp.Packet) (unit.Payload, error) {
type rtpDecoderVP9 (line 44) | type rtpDecoderVP9
method decode (line 46) | func (d *rtpDecoderVP9) decode(pkt *rtp.Packet) (unit.Payload, error) {
type rtpDecoderVP8 (line 59) | type rtpDecoderVP8
method decode (line 61) | func (d *rtpDecoderVP8) decode(pkt *rtp.Packet) (unit.Payload, error) {
type rtpDecoderH265 (line 74) | type rtpDecoderH265
method decode (line 76) | func (d *rtpDecoderH265) decode(pkt *rtp.Packet) (unit.Payload, error) {
type rtpDecoderH264 (line 89) | type rtpDecoderH264
method decode (line 91) | func (d *rtpDecoderH264) decode(pkt *rtp.Packet) (unit.Payload, error) {
type rtpDecoderMPEG4Video (line 104) | type rtpDecoderMPEG4Video
method decode (line 106) | func (d *rtpDecoderMPEG4Video) decode(pkt *rtp.Packet) (unit.Payload, ...
type rtpDecoderMPEG1Video (line 118) | type rtpDecoderMPEG1Video
method decode (line 120) | func (d *rtpDecoderMPEG1Video) decode(pkt *rtp.Packet) (unit.Payload, ...
type rtpDecoderMJPEG (line 133) | type rtpDecoderMJPEG
method decode (line 135) | func (d *rtpDecoderMJPEG) decode(pkt *rtp.Packet) (unit.Payload, error) {
type rtpDecoderOpus (line 148) | type rtpDecoderOpus
method decode (line 150) | func (d *rtpDecoderOpus) decode(pkt *rtp.Packet) (unit.Payload, error) {
type rtpDecoderMPEG4Audio (line 159) | type rtpDecoderMPEG4Audio
method decode (line 161) | func (d *rtpDecoderMPEG4Audio) decode(pkt *rtp.Packet) (unit.Payload, ...
type rtpDecoderMPEG4AudioLATM (line 173) | type rtpDecoderMPEG4AudioLATM
method decode (line 175) | func (d *rtpDecoderMPEG4AudioLATM) decode(pkt *rtp.Packet) (unit.Paylo...
type rtpDecoderMPEG1Audio (line 187) | type rtpDecoderMPEG1Audio
method decode (line 189) | func (d *rtpDecoderMPEG1Audio) decode(pkt *rtp.Packet) (unit.Payload, ...
type rtpDecoderAC3 (line 202) | type rtpDecoderAC3
method decode (line 204) | func (d *rtpDecoderAC3) decode(pkt *rtp.Packet) (unit.Payload, error) {
type rtpDecoderG711 (line 216) | type rtpDecoderG711
method decode (line 218) | func (d *rtpDecoderG711) decode(pkt *rtp.Packet) (unit.Payload, error) {
type rtpDecoderLPCM (line 227) | type rtpDecoderLPCM
method decode (line 229) | func (d *rtpDecoderLPCM) decode(pkt *rtp.Packet) (unit.Payload, error) {
type rtpDecoderKLV (line 238) | type rtpDecoderKLV
method decode (line 240) | func (d *rtpDecoderKLV) decode(pkt *rtp.Packet) (unit.Payload, error) {
function newRTPDecoder (line 249) | func newRTPDecoder(forma format.Format) (rtpDecoder, error) {
FILE: internal/stream/rtp_encoder.go
function ptrOf (line 26) | func ptrOf[T any](v T) *T {
type rtpEncoderNotAvailableError (line 32) | type rtpEncoderNotAvailableError struct
method Error (line 36) | func (e rtpEncoderNotAvailableError) Error() string {
type rtpEncoder (line 40) | type rtpEncoder interface
type rtpEncoderH265 (line 44) | type rtpEncoderH265
method encode (line 46) | func (e *rtpEncoderH265) encode(payload unit.Payload) ([]*rtp.Packet, ...
type rtpEncoderH264 (line 50) | type rtpEncoderH264
method encode (line 52) | func (e *rtpEncoderH264) encode(payload unit.Payload) ([]*rtp.Packet, ...
type rtpEncoderAV1 (line 56) | type rtpEncoderAV1
method encode (line 58) | func (e *rtpEncoderAV1) encode(payload unit.Payload) ([]*rtp.Packet, e...
type rtpEncoderVP9 (line 62) | type rtpEncoderVP9
method encode (line 64) | func (e *rtpEncoderVP9) encode(payload unit.Payload) ([]*rtp.Packet, e...
type rtpEncoderVP8 (line 68) | type rtpEncoderVP8
method encode (line 70) | func (e *rtpEncoderVP8) encode(payload unit.Payload) ([]*rtp.Packet, e...
type rtpEncoderMPEG4Video (line 74) | type rtpEncoderMPEG4Video
method encode (line 76) | func (e *rtpEncoderMPEG4Video) encode(payload unit.Payload) ([]*rtp.Pa...
type rtpEncoderMPEG1Video (line 80) | type rtpEncoderMPEG1Video
method encode (line 82) | func (e *rtpEncoderMPEG1Video) encode(payload unit.Payload) ([]*rtp.Pa...
type rtpEncoderMJPEG (line 86) | type rtpEncoderMJPEG
method encode (line 88) | func (e *rtpEncoderMJPEG) encode(payload unit.Payload) ([]*rtp.Packet,...
type rtpEncoderOpus (line 92) | type rtpEncoderOpus
method encode (line 94) | func (e *rtpEncoderOpus) encode(payload unit.Payload) ([]*rtp.Packet, ...
type rtpEncoderMPEG4Audio (line 112) | type rtpEncoderMPEG4Audio
method encode (line 114) | func (e *rtpEncoderMPEG4Audio) encode(payload unit.Payload) ([]*rtp.Pa...
type rtpEncoderMPEG4AudioLATM (line 118) | type rtpEncoderMPEG4AudioLATM
method encode (line 120) | func (e *rtpEncoderMPEG4AudioLATM) encode(payload unit.Payload) ([]*rt...
type rtpEncoderMPEG1Audio (line 124) | type rtpEncoderMPEG1Audio
method encode (line 126) | func (e *rtpEncoderMPEG1Audio) encode(payload unit.Payload) ([]*rtp.Pa...
type rtpEncoderAC3 (line 130) | type rtpEncoderAC3
method encode (line 132) | func (e *rtpEncoderAC3) encode(payload unit.Payload) ([]*rtp.Packet, e...
type rtpEncoderG711 (line 136) | type rtpEncoderG711
method encode (line 138) | func (e *rtpEncoderG711) encode(payload unit.Payload) ([]*rtp.Packet, ...
type rtpEncoderLPCM (line 142) | type rtpEncoderLPCM
method encode (line 144) | func (e *rtpEncoderLPCM) encode(payload unit.Payload) ([]*rtp.Packet, ...
type rtpEncoderKLV (line 148) | type rtpEncoderKLV
method encode (line 150) | func (e *rtpEncoderKLV) encode(payload unit.Payload) ([]*rtp.Packet, e...
function newRTPEncoder (line 154) | func newRTPEncoder(
FILE: internal/stream/stream.go
function mediasFromAlwaysAvailableFile (line 23) | func mediasFromAlwaysAvailableFile(alwaysAvailableFile string) ([]*descr...
function mediasFromAlwaysAvailableTracks (line 120) | func mediasFromAlwaysAvailableTracks(alwaysAvailableTracks []conf.Always...
function cloneFormat (line 226) | func cloneFormat(forma format.Format) format.Format {
function cloneDesc (line 291) | func cloneDesc(desc *description.Session) *description.Session {
type Stream (line 314) | type Stream struct
method Initialize (line 345) | func (s *Stream) Initialize() error {
method Close (line 424) | func (s *Stream) Close() {
method StartOfflineSubStream (line 440) | func (s *Stream) StartOfflineSubStream() error {
method InboundBytes (line 463) | func (s *Stream) InboundBytes() uint64 {
method OutboundBytes (line 468) | func (s *Stream) OutboundBytes() uint64 {
method InboundFramesInError (line 487) | func (s *Stream) InboundFramesInError() uint64 {
method RTSPStream (line 492) | func (s *Stream) RTSPStream(server *gortsplib.Server) *gortsplib.Serve...
method RTSPSStream (line 510) | func (s *Stream) RTSPSStream(server *gortsplib.Server) *gortsplib.Serv...
method AddReader (line 529) | func (s *Stream) AddReader(r *Reader) {
method RemoveReader (line 556) | func (s *Stream) RemoveReader(r *Reader) {
method WaitForReaders (line 575) | func (s *Stream) WaitForReaders() {
method addInboundBytes (line 579) | func (s *Stream) addInboundBytes(v uint64) {
method addOutboundBytes (line 583) | func (s *Stream) addOutboundBytes(v uint64) {
method updateLastTime (line 587) | func (s *Stream) updateLastTime(pts time.Duration) {
method writeRTSP (line 600) | func (s *Stream) writeRTSP(medi *description.Media, pkts []*rtp.Packet...
FILE: internal/stream/stream_alwaysavailable_test.go
function TestStreamAlwaysAvailableErrors (line 19) | func TestStreamAlwaysAvailableErrors(t *testing.T) {
function TestStreamAlwaysAvailable (line 129) | func TestStreamAlwaysAvailable(t *testing.T) {
FILE: internal/stream/stream_format.go
function multiplyAndDivide (line 17) | func multiplyAndDivide(v, m, d int64) int64 {
function unitSize (line 23) | func unitSize(u *unit.Unit) uint64 {
function randUint32 (line 31) | func randUint32() (uint32, error) {
type streamFormat (line 40) | type streamFormat struct
method initialize (line 62) | func (sf *streamFormat) initialize() error {
FILE: internal/stream/stream_media.go
type streamMedia (line 13) | type streamMedia struct
method initialize (line 28) | func (sm *streamMedia) initialize() error {
FILE: internal/stream/stream_standard_test.go
type nilLogger (line 14) | type nilLogger struct
method Log (line 16) | func (nilLogger) Log(logger.Level, string, ...any) {
function TestStream (line 19) | func TestStream(t *testing.T) {
function TestStreamSkipBytesSent (line 72) | func TestStreamSkipBytesSent(t *testing.T) {
function TestStreamResizeOversizedRTPPackets (line 127) | func TestStreamResizeOversizedRTPPackets(t *testing.T) {
function TestStreamUpdateFormatParams (line 236) | func TestStreamUpdateFormatParams(t *testing.T) {
function TestStreamDecode (line 1218) | func TestStreamDecode(t *testing.T) {
function TestStreamEncode (line 1268) | func TestStreamEncode(t *testing.T) {
FILE: internal/stream/sub_stream.go
function FormatsToCodecs (line 15) | func FormatsToCodecs(formats []format.Format) []string {
function gatherFormats (line 23) | func gatherFormats(medias []*description.Media) []format.Format {
function mediasToCodecs (line 43) | func mediasToCodecs(medias []*description.Media) []string {
function formatMPEG4AudioConfig (line 47) | func formatMPEG4AudioConfig(asc *mpeg4audio.AudioSpecificConfig) string {
function formatG711Config (line 52) | func formatG711Config(f *format.G711) string {
function formatLPCMConfig (line 57) | func formatLPCMConfig(f *format.LPCM) string {
function mediasAreCompatible (line 62) | func mediasAreCompatible(medias1 []*description.Media, medias2 []*descri...
type SubStream (line 120) | type SubStream struct
method Initialize (line 129) | func (ss *SubStream) Initialize() error {
method WriteUnit (line 198) | func (ss *SubStream) WriteUnit(medi *description.Media, forma format.F...
FILE: internal/stream/sub_stream_format.go
type subStreamFormat (line 13) | type subStreamFormat struct
method initialize (line 23) | func (ssf *subStreamFormat) initialize() error {
method initialize2 (line 48) | func (ssf *subStreamFormat) initialize2(firstTimeReceived bool, lastPT...
method writeUnit (line 94) | func (ssf *subStreamFormat) writeUnit(u *unit.Unit) {
method writeUnitInner (line 102) | func (ssf *subStreamFormat) writeUnitInner(u *unit.Unit) error {
FILE: internal/stream/sub_stream_media.go
type subStreamMedia (line 8) | type subStreamMedia struct
method initialize (line 16) | func (ssm *subStreamMedia) initialize() error {
FILE: internal/stream/unit_remuxer.go
type unitRemuxer (line 13) | type unitRemuxer
function unitRemuxerH265 (line 15) | func unitRemuxerH265(forma format.Format, payload unit.Payload) unit.Pay...
function unitRemuxerH264 (line 77) | func unitRemuxerH264(forma format.Format, payload unit.Payload) unit.Pay...
function unitRemuxerMPEG4Video (line 138) | func unitRemuxerMPEG4Video(forma format.Format, payload unit.Payload) un...
function newUnitRemuxer (line 165) | func newUnitRemuxer(forma format.Format) unitRemuxer {
FILE: internal/test/auth_manager.go
type AuthManager (line 7) | type AuthManager struct
method Authenticate (line 13) | func (m *AuthManager) Authenticate(req *auth.Request) (string, *auth.E...
method RefreshJWTJWKS (line 18) | func (m *AuthManager) RefreshJWTJWKS() {
FILE: internal/test/logger.go
type nilLogger (line 5) | type nilLogger struct
method Log (line 7) | func (nilLogger) Log(_ logger.Level, _ string, _ ...any) {
type testLogger (line 13) | type testLogger struct
method Log (line 17) | func (l *testLogger) Log(level logger.Level, format string, args ...an...
function Logger (line 22) | func Logger(cb func(logger.Level, string, ...any)) logger.Writer {
FILE: internal/test/medias.go
function UniqueMediaH264 (line 15) | func UniqueMediaH264() *description.Media {
function UniqueMediaMPEG4Audio (line 23) | func UniqueMediaMPEG4Audio() *description.Media {
FILE: internal/test/path_manager.go
type PathManager (line 8) | type PathManager struct
method FindPathConf (line 16) | func (pm *PathManager) FindPathConf(req defs.PathFindPathConfReq) (*de...
method Describe (line 21) | func (pm *PathManager) Describe(req defs.PathDescribeReq) defs.PathDes...
method AddPublisher (line 26) | func (pm *PathManager) AddPublisher(req defs.PathAddPublisherReq) (*de...
method AddReader (line 31) | func (pm *PathManager) AddReader(req defs.PathAddReaderReq) (*defs.Pat...
FILE: internal/test/static_source_parent.go
type StaticSourceParent (line 11) | type StaticSourceParent struct
method Log (line 18) | func (*StaticSourceParent) Log(logger.Level, string, ...any) {}
method Initialize (line 21) | func (p *StaticSourceParent) Initialize() {
method Close (line 26) | func (p *StaticSourceParent) Close() {
method SetReady (line 31) | func (p *StaticSourceParent) SetReady(req defs.PathSourceStaticSetRead...
method SetNotReady (line 70) | func (StaticSourceParent) SetNotReady(_ defs.PathSourceStaticSetNotRea...
FILE: internal/test/temp_file.go
function CreateTempFile (line 6) | func CreateTempFile(byts []byte) (string, error) {
FILE: internal/teste2e/build_images_test.go
function buildImage (line 14) | func buildImage(image string) error {
function TestBuildImages (line 22) | func TestBuildImages(t *testing.T) {
FILE: internal/teste2e/hls_manager_test.go
function TestHLSServerRead (line 13) | func TestHLSServerRead(t *testing.T) {
function TestHLSServerAuth (line 43) | func TestHLSServerAuth(t *testing.T) {
FILE: internal/teste2e/images/gstreamer/exitafterframe.c
type GstExitAfterFrame (line 9) | typedef struct
type GstExitAfterFrameClass (line 17) | typedef struct
function GstFlowReturn (line 40) | static GstFlowReturn
function gst_exitafterframe_class_init (line 48) | static void
function gst_exitafterframe_init (line 66) | static void
function gboolean (line 81) | static gboolean
FILE: internal/teste2e/rtsp_server_test.go
function TestRTSPServerPublishRead (line 14) | func TestRTSPServerPublishRead(t *testing.T) {
function TestRTSPServerRedirect (line 201) | func TestRTSPServerRedirect(t *testing.T) {
FILE: internal/teste2e/tests_test.go
function newInstance (line 15) | func newInstance(conf string) (*core.Core, bool) {
type container (line 29) | type container struct
method close (line 63) | func (c *container) close() {
method wait (line 69) | func (c *container) wait() int {
function newContainer (line 33) | func newContainer(image string, name string, args []string) (*container,...
FILE: internal/unit/payload.go
type Payload (line 4) | type Payload interface
FILE: internal/unit/payload_ac3.go
type PayloadAC3 (line 4) | type PayloadAC3
method isPayload (line 6) | func (PayloadAC3) isPayload() {}
FILE: internal/unit/payload_av1.go
type PayloadAV1 (line 4) | type PayloadAV1
method isPayload (line 6) | func (PayloadAV1) isPayload() {}
FILE: internal/unit/payload_g711.go
type PayloadG711 (line 4) | type PayloadG711
method isPayload (line 6) | func (PayloadG711) isPayload() {}
FILE: internal/unit/payload_h264.go
type PayloadH264 (line 4) | type PayloadH264
method isPayload (line 6) | func (PayloadH264) isPayload() {}
FILE: internal/unit/payload_h265.go
type PayloadH265 (line 4) | type PayloadH265
method isPayload (line 6) | func (PayloadH265) isPayload() {}
FILE: internal/unit/payload_klv.go
type PayloadKLV (line 4) | type PayloadKLV
method isPayload (line 6) | func (PayloadKLV) isPayload() {}
FILE: internal/unit/payload_lpcm.go
type PayloadLPCM (line 4) | type PayloadLPCM
method isPayload (line 6) | func (PayloadLPCM) isPayload() {}
FILE: internal/unit/payload_mjpeg.go
type PayloadMJPEG (line 4) | type PayloadMJPEG
method isPayload (line 6) | func (PayloadMJPEG) isPayload() {}
FILE: internal/unit/payload_mpeg1_audio.go
type PayloadMPEG1Audio (line 4) | type PayloadMPEG1Audio
method isPayload (line 6) | func (PayloadMPEG1Audio) isPayload() {}
FILE: internal/unit/payload_mpeg1_video.go
type PayloadMPEG1Video (line 4) | type PayloadMPEG1Video
method isPayload (line 6) | func (PayloadMPEG1Video) isPayload() {}
FILE: internal/unit/payload_mpeg4_audio.go
type PayloadMPEG4Audio (line 4) | type PayloadMPEG4Audio
method isPayload (line 6) | func (PayloadMPEG4Audio) isPayload() {}
FILE: internal/unit/payload_mpeg4_audio_latm.go
type PayloadMPEG4AudioLATM (line 4) | type PayloadMPEG4AudioLATM
method isPayload (line 6) | func (PayloadMPEG4AudioLATM) isPayload() {}
FILE: internal/unit/payload_mpeg4_video.go
type PayloadMPEG4Video (line 4) | type PayloadMPEG4Video
method isPayload (line 6) | func (PayloadMPEG4Video) isPayload() {}
FILE: internal/unit/payload_opus.go
type PayloadOpus (line 4) | type PayloadOpus
method isPayload (line 6) | func (PayloadOpus) isPayload() {}
FILE: internal/unit/payload_vp8.go
type PayloadVP8 (line 4) | type PayloadVP8
method isPayload (line 6) | func (PayloadVP8) isPayload() {}
FILE: internal/unit/payload_vp9.go
type PayloadVP9 (line 4) | type PayloadVP9
method isPayload (line 6) | func (PayloadVP9) isPayload() {}
FILE: internal/unit/unit.go
type Unit (line 12) | type Unit struct
method NilPayload (line 27) | func (u Unit) NilPayload() bool {
FILE: main.go
function main (line 10) | func main() {
Condensed preview — 473 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,213K chars).
[
{
"path": ".dockerignore",
"chars": 252,
"preview": "# do not add .git, since it is needed to extract the tag\n# do not add /binaries, since it is needed by Docker images\n/tm"
},
{
"path": ".github/DISCUSSION_TEMPLATE/questions.yml",
"chars": 793,
"preview": "body:\n - type: markdown\n attributes:\n value: |\n * Please create a discussion FOR EACH question. Do not a"
},
{
"path": ".github/ISSUE_TEMPLATE/bug.yml",
"chars": 2694,
"preview": "name: Bug report\ndescription: Report a bug\n\nbody:\n - type: markdown\n attributes:\n value: |\n To increase "
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 184,
"preview": "blank_issues_enabled: false\n\ncontact_links:\n - name: Question\n url: https://github.com/bluenviron/mediamtx/discussio"
},
{
"path": ".github/ISSUE_TEMPLATE/feature.yml",
"chars": 406,
"preview": "name: Feature request\ndescription: Share ideas for new features\n\nbody:\n - type: markdown\n attributes:\n value: |"
},
{
"path": ".github/dependabot.yml",
"chars": 207,
"preview": "version: 2\nupdates:\n\n - package-ecosystem: \"gomod\"\n directory: \"/\"\n schedule:\n interval: \"daily\"\n\n - packag"
},
{
"path": ".github/workflows/lint.yml",
"chars": 1151,
"preview": "name: lint\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\njobs:\n go:\n runs-on: ubuntu-2"
},
{
"path": ".github/workflows/nightly_binaries.yml",
"chars": 305,
"preview": "name: nightly_binaries\n\non:\n workflow_dispatch:\n\njobs:\n nightly_binaries:\n runs-on: ubuntu-22.04\n\n steps:\n - "
},
{
"path": ".github/workflows/release.yml",
"chars": 4520,
"preview": "name: release\n\non:\n push:\n tags:\n - 'v*'\n\npermissions:\n id-token: write\n attestations: write\n artifact-metadat"
},
{
"path": ".github/workflows/test.yml",
"chars": 693,
"preview": "name: test\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\njobs:\n test_64:\n runs-on: ubu"
},
{
"path": ".gitignore",
"chars": 145,
"preview": "/tmp\n/binaries\n/coverage*.txt\n/api/*.html\n/internal/core/VERSION\n/internal/servers/hls/hls.min.js\n/internal/staticsource"
},
{
"path": ".golangci.yml",
"chars": 1940,
"preview": "version: \"2\"\n\nlinters:\n enable:\n - asciicheck\n - bidichk\n - bodyclose\n - copyloopvar\n - dupl\n - errorlint\n - goc"
},
{
"path": "LICENSE",
"chars": 1062,
"preview": "MIT License\n\nCopyright (c) 2019 aler9\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof t"
},
{
"path": "Makefile",
"chars": 654,
"preview": "BASE_IMAGE = golang:1.25-alpine3.22\nGOLANGCI_LINT_IMAGE = golangci/golangci-lint:v2.11.3\nNODE_IMAGE = node:20-alpine3.22"
},
{
"path": "README.md",
"chars": 3298,
"preview": "<h1 align=\"center\">\n <a href=\"https://mediamtx.org\">\n <img src=\"logo.png\" alt=\"MediaMTX\">\n </a>\n\n <br>\n <br>\n\n ["
},
{
"path": "SECURITY.md",
"chars": 96,
"preview": "# Security\n\nCheck the [Security page](https://mediamtx.org/docs/other/security) on the website.\n"
},
{
"path": "api/.redocly.yaml",
"chars": 63,
"preview": "extends:\n - recommended\n\nrules:\n operation-4xx-response: off\n"
},
{
"path": "api/openapi.yaml",
"chars": 87147,
"preview": "openapi: 3.0.0\n\ninfo:\n version: 1.0.0\n title: MediaMTX API\n description: API of MediaMTX, a server and proxy that sup"
},
{
"path": "docker/ffmpeg-rpi.Dockerfile",
"chars": 2183,
"preview": "#################################################################\nFROM --platform=linux/amd64 scratch AS binaries\n\nADD b"
},
{
"path": "docker/ffmpeg.Dockerfile",
"chars": 544,
"preview": "#################################################################\nFROM --platform=linux/amd64 scratch AS binaries\n\nADD b"
},
{
"path": "docker/rpi.Dockerfile",
"chars": 2075,
"preview": "#################################################################\nFROM --platform=linux/amd64 scratch AS binaries\n\nADD b"
},
{
"path": "docker/standard.Dockerfile",
"chars": 509,
"preview": "#################################################################\nFROM --platform=linux/amd64 scratch AS binaries\n\nADD b"
},
{
"path": "docs/1-kickoff/1-introduction.md",
"chars": 1917,
"preview": "# Introduction\n\nWelcome to the MediaMTX documentation!\n\n_MediaMTX_ is a ready-to-use and zero-dependency live media serv"
},
{
"path": "docs/1-kickoff/2-install.md",
"chars": 4161,
"preview": "# Install\n\nThere are several installation methods available:\n\n- [Standalone binary](#standalone-binary): use this if you"
},
{
"path": "docs/1-kickoff/3-upgrade.md",
"chars": 1019,
"preview": "# Upgrade\n\nIf you have an existing _MediaMTX_ installation, you can upgrade it to the latest version. The procedure depe"
},
{
"path": "docs/1-kickoff/4-basic-usage.md",
"chars": 827,
"preview": "# Basic usage\n\n1. [Publish](../2-publish/01-overview.md) a stream. For instance, you can publish a stream from a MP4 fil"
},
{
"path": "docs/1-kickoff/index.md",
"chars": 10,
"preview": "# Kickoff\n"
},
{
"path": "docs/2-publish/01-overview.md",
"chars": 5199,
"preview": "# Publish a stream\n\nLive streams can be published to the server with the following protocols and codecs:\n\n| protocol "
},
{
"path": "docs/2-publish/02-srt-clients.md",
"chars": 938,
"preview": "# SRT clients\n\nSRT is a protocol that allows to publish and read live data stream, providing encryption, integrity and a"
},
{
"path": "docs/2-publish/03-srt-cameras-and-servers.md",
"chars": 388,
"preview": "# SRT cameras and servers\n\nIn order to ingest a SRT stream from a remote server, camera or client in listening mode (i.e"
},
{
"path": "docs/2-publish/04-webrtc-clients.md",
"chars": 1291,
"preview": "# WebRTC clients\n\nWebRTC is an API that makes use of a set of protocols and methods to connect two clients together and "
},
{
"path": "docs/2-publish/05-webrtc-servers.md",
"chars": 555,
"preview": "# WebRTC servers\n\nIn order to ingest a WebRTC stream from a remote server, add the corresponding WHEP URL into the `sour"
},
{
"path": "docs/2-publish/06-rtsp-clients.md",
"chars": 1290,
"preview": "# RTSP clients\n\nRTSP is a protocol that allows to publish and read streams. It supports several underlying transport pro"
},
{
"path": "docs/2-publish/07-rtsp-cameras-and-servers.md",
"chars": 2260,
"preview": "# RTSP cameras and servers\n\nMost IP cameras expose their video stream by using a RTSP server that is embedded into the c"
},
{
"path": "docs/2-publish/08-rtmp-clients.md",
"chars": 456,
"preview": "# RTMP clients\n\nRTMP is a protocol that allows to read and publish streams. It supports encryption, read [RTMP-specific "
},
{
"path": "docs/2-publish/09-rtmp-cameras-and-servers.md",
"chars": 332,
"preview": "# RTMP cameras and servers\n\nYou can use _MediaMTX_ to connect to one or several existing RTMP servers and read their med"
},
{
"path": "docs/2-publish/10-hls-cameras-and-servers.md",
"chars": 501,
"preview": "# HLS cameras and servers\n\nHLS is a streaming protocol that works by splitting streams into segments, and by serving the"
},
{
"path": "docs/2-publish/11-mpeg-ts.md",
"chars": 1196,
"preview": "# MPEG-TS\n\nThe server supports ingesting MPEG-TS streams, shipped in two different ways (UDP packets or Unix sockets).\n\n"
},
{
"path": "docs/2-publish/12-rtp.md",
"chars": 788,
"preview": "# RTP\n\nThe server supports ingesting RTP streams, transmitted with UDP packets.\n\nIn order to read a UDP RTP stream, edit"
},
{
"path": "docs/2-publish/13-raspberry-pi-cameras.md",
"chars": 4054,
"preview": "# Raspberry Pi Cameras\n\n_MediaMTX_ natively supports most Raspberry Pi Camera models, enabling high-quality and low-late"
},
{
"path": "docs/2-publish/14-generic-webcams.md",
"chars": 797,
"preview": "# Generic webcams\n\nIf the operating system is Linux, edit `mediamtx.yml` and replace everything inside section `paths` w"
},
{
"path": "docs/2-publish/15-ffmpeg.md",
"chars": 1787,
"preview": "# FFmpeg\n\nFFmpeg can publish a stream to the server in several ways. The recommended one consists in publishing with RTS"
},
{
"path": "docs/2-publish/16-gstreamer.md",
"chars": 1843,
"preview": "# GStreamer\n\nGStreamer can publish a stream to the server in several ways. The recommended one consists in publishing wi"
},
{
"path": "docs/2-publish/17-obs-studio.md",
"chars": 4349,
"preview": "# OBS Studio\n\nOBS Studio can publish streams to the server in several ways. The recommended one consists in publishing w"
},
{
"path": "docs/2-publish/18-python-opencv.md",
"chars": 2023,
"preview": "# Python and OpenCV\n\nPython-based software can publish streams to the server with the OpenCV library and its GStreamer p"
},
{
"path": "docs/2-publish/19-golang.md",
"chars": 412,
"preview": "# Golang\n\nYou can publish a stream to the server by using the Go programming language and the following libraries:\n\n- [g"
},
{
"path": "docs/2-publish/20-unity.md",
"chars": 3440,
"preview": "# Unity\n\nSoftware written with the Unity Engine can publish a stream to the server by using the [WebRTC protocol](04-web"
},
{
"path": "docs/2-publish/21-web-browsers.md",
"chars": 896,
"preview": "# Web browsers\n\nWeb browsers can publish a stream to the server by using the [WebRTC protocol](04-webrtc-clients.md). St"
},
{
"path": "docs/2-publish/index.md",
"chars": 10,
"preview": "# Publish\n"
},
{
"path": "docs/3-read/01-overview.md",
"chars": 2706,
"preview": "# Read a stream\n\nLive streams can be read from the server with the following protocols and codecs:\n\n| protocol "
},
{
"path": "docs/3-read/02-srt.md",
"chars": 701,
"preview": "# SRT clients\n\nSRT is a protocol that allows to publish and read live data stream, providing encryption, integrity and a"
},
{
"path": "docs/3-read/03-webrtc.md",
"chars": 1132,
"preview": "# WebRTC clients\n\nWebRTC is an API that makes use of a set of protocols and methods to connect two clients together and "
},
{
"path": "docs/3-read/04-rtsp.md",
"chars": 437,
"preview": "# RTSP clients\n\nRTSP is a protocol that allows to publish and read streams. It supports several underlying transport pro"
},
{
"path": "docs/3-read/05-rtmp.md",
"chars": 378,
"preview": "# RTMP clients\n\nRTMP is a protocol that allows to read and publish streams. It supports encryption, read [RTMP-specific "
},
{
"path": "docs/3-read/06-hls.md",
"chars": 629,
"preview": "# HLS\n\nHLS is a protocol that works by splitting streams into segments, and by serving these segments and a playlist wit"
},
{
"path": "docs/3-read/07-ffmpeg.md",
"chars": 691,
"preview": "# FFmpeg\n\nFFmpeg can read a stream from the server in several ways. The recommended one consists in reading with RTSP.\n\n"
},
{
"path": "docs/3-read/08-gstreamer.md",
"chars": 1780,
"preview": "# GStreamer\n\nGStreamer can read a stream from the server in several ways. The recommended one consists in reading with R"
},
{
"path": "docs/3-read/09-vlc.md",
"chars": 876,
"preview": "# VLC\n\nVLC can read a stream from the server in several ways. The recommended one consists in reading with RTSP:\n\n```sh\n"
},
{
"path": "docs/3-read/10-obs-studio.md",
"chars": 247,
"preview": "# OBS Studio\n\nOBS Studio can read streams from the server by using the [RTSP protocol](04-rtsp.md).\n\nOpen OBS, click on "
},
{
"path": "docs/3-read/11-python-opencv.md",
"chars": 520,
"preview": "# Python and OpenCV\n\nPython-based software can read streams from the server with the OpenCV library, acting as a [RTSP c"
},
{
"path": "docs/3-read/12-golang.md",
"chars": 480,
"preview": "# Golang\n\nYou can read a stream from the server by using the Go programming language and the following libraries:\n\n- [go"
},
{
"path": "docs/3-read/13-unity.md",
"chars": 4207,
"preview": "# Unity\n\nSoftware written with the Unity Engine can read a stream from the server by using the [WebRTC protocol](03-webr"
},
{
"path": "docs/3-read/14-web-browsers.md",
"chars": 959,
"preview": "# Web browsers\n\nWeb browsers can read a stream from the server in several ways.\n\n## Web browsers and WebRTC\n\nYou can rea"
},
{
"path": "docs/3-read/index.md",
"chars": 7,
"preview": "# Read\n"
},
{
"path": "docs/4-other/02-configuration.md",
"chars": 2503,
"preview": "# Configuration\n\nAll the configuration parameters are listed and commented in the [configuration file](../5-references/1"
},
{
"path": "docs/4-other/03-authentication.md",
"chars": 13933,
"preview": "# Authentication\n\n_MediaMTX_ can be configured to ask clients for credentials, either in the form of username/password o"
},
{
"path": "docs/4-other/04-remuxing-reencoding-compression.md",
"chars": 662,
"preview": "# Re-encoding\n\nTo change the format, codec or compression of a stream, use _FFmpeg_ or _GStreamer_ together with _MediaM"
},
{
"path": "docs/4-other/05-always-available.md",
"chars": 1161,
"preview": "# Always-available\n\nWhen the publisher or source of a stream is offline, the server can be configured to fill gaps in th"
},
{
"path": "docs/4-other/06-record.md",
"chars": 3330,
"preview": "# Record\n\nLive streams be recorded to disk and played back with the following file containers and codecs:\n\n| container |"
},
{
"path": "docs/4-other/07-playback.md",
"chars": 2180,
"preview": "# Playback\n\nExisting recordings can be played back to users through a dedicated HTTP server, that can be enabled inside "
},
{
"path": "docs/4-other/08-forward.md",
"chars": 287,
"preview": "# Forward\n\nTo forward incoming streams to another server, use _FFmpeg_ inside the `runOnReady` parameter:\n\n```yml\npathDe"
},
{
"path": "docs/4-other/09-proxy.md",
"chars": 568,
"preview": "# Proxy\n\nThe server allows to proxy incoming requests to other servers or cameras. This is useful to expose servers or c"
},
{
"path": "docs/4-other/10-extract-snapshots.md",
"chars": 422,
"preview": "# Extract snapshots\n\nYou can periodically extract snapshots from available streams by using FFmpeg inside the `runOnRead"
},
{
"path": "docs/4-other/11-on-demand-publishing.md",
"chars": 449,
"preview": "# On-demand publishing\n\nEdit `mediamtx.yml` and replace everything inside section `paths` with the following content:\n\n`"
},
{
"path": "docs/4-other/12-absolute-timestamps.md",
"chars": 3398,
"preview": "# Route absolute timestamps\n\nSome streaming protocols allow to route absolute timestamps, associated with each frame, th"
},
{
"path": "docs/4-other/13-expose-the-server-in-a-subfolder.md",
"chars": 1586,
"preview": "# Expose the server in a subfolder\n\nHTTP-based services (WebRTC, HLS, Control API, Playback Server, Metrics, pprof) can "
},
{
"path": "docs/4-other/14-embed-streams-in-a-website.md",
"chars": 6884,
"preview": "# Embed streams in a website\n\nLive streams can be embedded into an external website by using the WebRTC or HLS protocol."
},
{
"path": "docs/4-other/15-start-on-boot.md",
"chars": 2290,
"preview": "# Start on boot\n\n## Linux\n\nOn most Linux distributions (including Ubuntu and Debian, but not OpenWrt), _systemd_ is in c"
},
{
"path": "docs/4-other/16-logging.md",
"chars": 2772,
"preview": "# Logging\n\n## Log verbosity\n\nLog verbosity can be set with the `logLevel` parameter:\n\n```yml\n# Verbosity of the program;"
},
{
"path": "docs/4-other/17-hooks.md",
"chars": 6098,
"preview": "# Hooks\n\nThe server allows to specify commands that are executed when a certain event happens, allowing the propagation "
},
{
"path": "docs/4-other/18-control-api.md",
"chars": 635,
"preview": "# Control API\n\nThe server can be queried and controlled with an API, that can be enabled by toggling the `api` parameter"
},
{
"path": "docs/4-other/19-metrics.md",
"chars": 11311,
"preview": "# Extract metrics\n\n_MediaMTX_ provides several metrics through a dedicated HTTP server, in a format compatible with [Pro"
},
{
"path": "docs/4-other/20-performance.md",
"chars": 13520,
"preview": "# Monitor performance\n\nCPU and memory consumption can be monitored over time through an integrated performance monitor, "
},
{
"path": "docs/4-other/21-srt-specific-features.md",
"chars": 1101,
"preview": "# SRT-specific features\n\nSRT is a protocol that can be used for publishing and reading streams. Regarding specific tasks"
},
{
"path": "docs/4-other/22-webrtc-specific-features.md",
"chars": 6341,
"preview": "# WebRTC-specific features\n\nWebRTC is a protocol that can be used for publishing and reading streams. Regarding specific"
},
{
"path": "docs/4-other/23-rtsp-specific-features.md",
"chars": 4394,
"preview": "# RTSP-specific features\n\nRTSP is a protocol that can be used for publishing and reading streams. Regarding specific tas"
},
{
"path": "docs/4-other/24-rtmp-specific-features.md",
"chars": 1324,
"preview": "# RTMP-specific features\n\nRTMP is a protocol that can be used for publishing and reading streams. Regarding specific tas"
},
{
"path": "docs/4-other/25-decrease-packet-loss.md",
"chars": 2322,
"preview": "# Decrease packet loss\n\nMediaMTX is meant for routing live streams, and makes use of a series of protocols and technique"
},
{
"path": "docs/4-other/index.md",
"chars": 17,
"preview": "# Other features\n"
},
{
"path": "docs/5-references/1-configuration-file.md",
"chars": 287,
"preview": "# Configuration file reference\n\nThis is a copy of the configuration file (`mediamtx.yml`) of the latest _MediaMTX_ relea"
},
{
"path": "docs/5-references/2-control-api.md",
"chars": 384,
"preview": "# Control API reference\n\nThis is the reference of the Control API of the latest _MediaMTX_ release ({version_tag}), gene"
},
{
"path": "docs/5-references/index.md",
"chars": 13,
"preview": "# References\n"
},
{
"path": "docs/6-misc/1-compile.md",
"chars": 3252,
"preview": "# Compile from source\n\n## Standard procedure\n\n1. Install git and Go ≥ 1.25.\n\n2. Clone the repository, enter into the "
},
{
"path": "docs/6-misc/2-license.md",
"chars": 752,
"preview": "# License\n\nAll the code in the main _MediaMTX_ repository is released under the [MIT License](https://github.com/bluenvi"
},
{
"path": "docs/6-misc/3-security.md",
"chars": 1513,
"preview": "# Security\n\n## Security of released binaries\n\nBinaries published in the [Releases](https://github.com/bluenviron/mediamt"
},
{
"path": "docs/6-misc/4-specifications.md",
"chars": 2114,
"preview": "# Specifications\n\n| name "
},
{
"path": "docs/6-misc/5-related-projects.md",
"chars": 1120,
"preview": "# Related projects\n\n- [gortsplib (RTSP library used internally)](https://github.com/bluenviron/gortsplib)\n- [gohlslib (H"
},
{
"path": "docs/6-misc/index.md",
"chars": 7,
"preview": "# Misc\n"
},
{
"path": "docs/redirects.yaml",
"chars": 1530,
"preview": "kickoff/installation: kickoff/install\n\nusage/publish: publish/overview\nusage/read: read/overview\nusage/log-management: o"
},
{
"path": "go.mod",
"chars": 4423,
"preview": "module github.com/bluenviron/mediamtx\n\ngo 1.25.0\n\nrequire (\n\tcode.cloudfoundry.org/bytefmt v0.67.0\n\tgithub.com/Mastermin"
},
{
"path": "go.sum",
"chars": 28496,
"preview": "aead.dev/minisign v0.2.0 h1:kAWrq/hBRu4AARY6AlciO83xhNnW9UaC8YipS2uhLPk=\naead.dev/minisign v0.2.0/go.mod h1:zdq6LdSd9Tbu"
},
{
"path": "internal/api/api.go",
"chars": 8008,
"preview": "// Package api contains the API server.\npackage api //nolint:revive\n\nimport (\n\t\"net\"\n\t\"net/http\"\n\t\"reflect\"\n\t\"sort\"\n\t\"sy"
},
{
"path": "internal/api/api_config_global.go",
"chars": 915,
"preview": "package api //nolint:revive\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf\"\n\t\"github.com/bluenvir"
},
{
"path": "internal/api/api_config_global_test.go",
"chars": 3303,
"preview": "package api //nolint:revive\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/"
},
{
"path": "internal/api/api_config_pathdefaults.go",
"chars": 831,
"preview": "package api //nolint:revive\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf\"\n\t\"github.com/bluenvir"
},
{
"path": "internal/api/api_config_pathdefaults_test.go",
"chars": 1705,
"preview": "package api //nolint:revive\n\nimport (\n\t\"net/http\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf\"\n\t\""
},
{
"path": "internal/api/api_config_paths.go",
"chars": 4154,
"preview": "package api //nolint:revive\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf\"\n\t\"gi"
},
{
"path": "internal/api/api_config_paths_test.go",
"chars": 9328,
"preview": "package api //nolint:revive\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/"
},
{
"path": "internal/api/api_hls.go",
"chars": 1059,
"preview": "//nolint:dupl\npackage api //nolint:revive\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/bluenviron/mediamtx/inter"
},
{
"path": "internal/api/api_hls_test.go",
"chars": 3219,
"preview": "package api //nolint:revive\n\nimport (\n\t\"net/http\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf\"\n\t\""
},
{
"path": "internal/api/api_paths.go",
"chars": 1046,
"preview": "//nolint:dupl\npackage api //nolint:revive\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/bluenviron/mediamtx/inter"
},
{
"path": "internal/api/api_paths_test.go",
"chars": 4398,
"preview": "package api //nolint:revive\n\nimport (\n\t\"net/http\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf\"\n\t\""
},
{
"path": "internal/api/api_recordings.go",
"chars": 2155,
"preview": "package api //nolint:revive\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/bluenviron/mediamtx/inte"
},
{
"path": "internal/api/api_recordings_test.go",
"chars": 4976,
"preview": "package api //nolint:revive\n\nimport (\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/blu"
},
{
"path": "internal/api/api_rtmp.go",
"chars": 2787,
"preview": "package api //nolint:revive\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/bluenviron/mediamtx/internal/servers/rtmp\"\n\t\"g"
},
{
"path": "internal/api/api_rtmp_test.go",
"chars": 6699,
"preview": "package api //nolint:revive\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/mediamtx/internal/c"
},
{
"path": "internal/api/api_rtsp.go",
"chars": 4603,
"preview": "package api //nolint:revive\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/bluenviron/mediamtx/internal/servers/rtsp\"\n\t\"g"
},
{
"path": "internal/api/api_rtsp_test.go",
"chars": 15158,
"preview": "package api //nolint:revive\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/me"
},
{
"path": "internal/api/api_srt.go",
"chars": 1482,
"preview": "//nolint:dupl\npackage api //nolint:revive\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/bluenviron/mediamtx/internal/ser"
},
{
"path": "internal/api/api_srt_test.go",
"chars": 7898,
"preview": "package api //nolint:revive\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/mediamtx/internal/c"
},
{
"path": "internal/api/api_test.go",
"chars": 6191,
"preview": "package api //nolint:revive\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"testing\"\n\t\"t"
},
{
"path": "internal/api/api_webrtc.go",
"chars": 1533,
"preview": "//nolint:dupl\npackage api //nolint:revive\n\nimport (\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/bluenviron/mediamtx/internal/ser"
},
{
"path": "internal/api/api_webrtc_test.go",
"chars": 8418,
"preview": "package api //nolint:revive\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/mediamtx/internal/c"
},
{
"path": "internal/api/paginate.go",
"chars": 1028,
"preview": "package api //nolint:revive\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n)\n\nfunc paginate2(itemsPtr any, itemsPerPage int, pag"
},
{
"path": "internal/api/paginate_test.go",
"chars": 1204,
"preview": "package api //nolint:revive\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestPaginate(t *testing"
},
{
"path": "internal/api/testdata/fuzz/FuzzPaginate/23731da0f18d31d0",
"chars": 40,
"preview": "go test fuzz v1\nstring(\"A\")\nstring(\"0\")\n"
},
{
"path": "internal/api/testdata/fuzz/FuzzPaginate/34523a772174e26e",
"chars": 40,
"preview": "go test fuzz v1\nstring(\"1\")\nstring(\"A\")\n"
},
{
"path": "internal/api/testdata/fuzz/FuzzPaginate/85649d45641911d0",
"chars": 39,
"preview": "go test fuzz v1\nstring(\"0\")\nstring(\"\")\n"
},
{
"path": "internal/auth/credentials.go",
"chars": 154,
"preview": "package auth\n\n// Credentials is a set of credentials (either user+pass or a token).\ntype Credentials struct {\n\tUser str"
},
{
"path": "internal/auth/error.go",
"chars": 246,
"preview": "package auth\n\n// Error is an authentication error.\ntype Error struct {\n\tWrapped error\n\tAskCredentials bool\n}\n\n// "
},
{
"path": "internal/auth/jwt_claims.go",
"chars": 984,
"preview": "package auth\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf\"\n\t\"github.com/bluenviron/"
},
{
"path": "internal/auth/manager.go",
"chars": 7555,
"preview": "// Package auth contains the authentication system.\npackage auth\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/"
},
{
"path": "internal/auth/manager_test.go",
"chars": 27312,
"preview": "package auth\n\nimport (\n\t\"context\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/tls\"\n\t\"encoding/json\"\n\t\"net\"\n\t\"net/http\"\n\t\"testi"
},
{
"path": "internal/auth/request.go",
"chars": 815,
"preview": "package auth\n\nimport (\n\t\"net\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf\"\n\t\"github.com/google/uuid\"\n)\n\n// Protocol "
},
{
"path": "internal/certloader/certloader.go",
"chars": 2603,
"preview": "// Package certloader contains a certicate loader.\npackage certloader\n\nimport (\n\t\"crypto/tls\"\n\t\"sync\"\n\n\t\"github.com/blue"
},
{
"path": "internal/certloader/certloader_test.go",
"chars": 1309,
"preview": "package certloader\n\nimport (\n\t\"crypto/tls\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/mediamtx/internal/test\"\n\t\"g"
},
{
"path": "internal/conf/always_available_track.go",
"chars": 1284,
"preview": "package conf\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n)\n\n// AlwaysAvailableTrack is"
},
{
"path": "internal/conf/always_available_track_codec.go",
"chars": 812,
"preview": "package conf\n\nimport \"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n\n// AlwaysAvailableTrackCodec is a codec"
},
{
"path": "internal/conf/auth_action.go",
"chars": 1067,
"preview": "package conf\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n)\n\n// AuthAction is an authen"
},
{
"path": "internal/conf/auth_internal_user.go",
"chars": 309,
"preview": "package conf\n\n// AuthInternalUser is an user.\ntype AuthInternalUser struct {\n\tUser Credential `"
},
{
"path": "internal/conf/auth_internal_user_permission.go",
"chars": 182,
"preview": "package conf\n\n// AuthInternalUserPermission is a permission of a user.\ntype AuthInternalUserPermission struct {\n\tAction "
},
{
"path": "internal/conf/auth_method.go",
"chars": 831,
"preview": "package conf\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n)\n\n// AuthMethod is an authen"
},
{
"path": "internal/conf/conf.go",
"chars": 36549,
"preview": "// Package conf contains the struct that holds the configuration of the software.\npackage conf\n\nimport (\n\t\"errors\"\n\t\"fmt"
},
{
"path": "internal/conf/conf_test.go",
"chars": 23082,
"preview": "package conf\n\nimport (\n\t\"crypto/rand\"\n\t\"encoding/base64\"\n\t\"io\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/gortspl"
},
{
"path": "internal/conf/credential.go",
"chars": 2798,
"preview": "package conf\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/bluenviron/mediamtx"
},
{
"path": "internal/conf/credential_test.go",
"chars": 3773,
"preview": "package conf\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestCredential(t *testing.T) {\n\tt.Run(\""
},
{
"path": "internal/conf/decrypt/decrypt.go",
"chars": 625,
"preview": "// Package decrypt contains the Decrypt function.\npackage decrypt\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\n\t\"golang.org/x/cr"
},
{
"path": "internal/conf/duration.go",
"chars": 1855,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jso"
},
{
"path": "internal/conf/duration_test.go",
"chars": 937,
"preview": "package conf\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nvar casesDuration = []struct {\n\tnam"
},
{
"path": "internal/conf/encryption.go",
"chars": 935,
"preview": "package conf\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n)\n\n// Encryption is the rtspE"
},
{
"path": "internal/conf/env/env.go",
"chars": 6557,
"preview": "// Package env contains a function to load configuration from environment.\npackage env\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"reflect\""
},
{
"path": "internal/conf/env/env_test.go",
"chars": 6670,
"preview": "package env\n\nimport (\n\t\"encoding/json\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc ptrOf[T any](v"
},
{
"path": "internal/conf/global.go",
"chars": 739,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"reflect\"\n)\n\nvar globalValuesType = func() reflect.Type {\n\tvar fields []reflect"
},
{
"path": "internal/conf/hls_variant.go",
"chars": 1175,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/bluenviron/gohlslib/v2\"\n\t\"github.com/bluenviron/mediamtx/in"
},
{
"path": "internal/conf/ip_network.go",
"chars": 1284,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n)\n\n//"
},
{
"path": "internal/conf/ip_networks.go",
"chars": 859,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"net\"\n\t\"strings\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n)"
},
{
"path": "internal/conf/jsonwrapper/testdata/fuzz/FuzzUnmarshal/297c43aee5d30530",
"chars": 157,
"preview": "go test fuzz v1\n[]byte(\"[0\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n"
},
{
"path": "internal/conf/jsonwrapper/testdata/fuzz/FuzzUnmarshal/7f71a2d116d5afde",
"chars": 31,
"preview": "go test fuzz v1\n[]byte(\"null\")\n"
},
{
"path": "internal/conf/jsonwrapper/unmarshal.go",
"chars": 3265,
"preview": "// Package jsonwrapper contains a JSON unmarshaler.\npackage jsonwrapper\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\""
},
{
"path": "internal/conf/jsonwrapper/unmarshal_test.go",
"chars": 3463,
"preview": "package jsonwrapper\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\ntype tes"
},
{
"path": "internal/conf/log_destination.go",
"chars": 1042,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n\t\"github.com"
},
{
"path": "internal/conf/log_destinations.go",
"chars": 696,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n\t\"github"
},
{
"path": "internal/conf/log_level.go",
"chars": 1155,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n\t\"github.com"
},
{
"path": "internal/conf/optional_global.go",
"chars": 1256,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrappe"
},
{
"path": "internal/conf/optional_path.go",
"chars": 1466,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/env\"\n\t\"git"
},
{
"path": "internal/conf/path.go",
"chars": 28684,
"preview": "package conf\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/url\"\n\t\"os\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\""
},
{
"path": "internal/conf/path_test.go",
"chars": 418,
"preview": "package conf\n\nimport (\n\t\"testing\"\n\n\t\"github.com/bluenviron/gortsplib/v5\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc "
},
{
"path": "internal/conf/record_format.go",
"chars": 789,
"preview": "package conf\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n)\n\n// RecordFormat is the rec"
},
{
"path": "internal/conf/rtsp_auth_method.go",
"chars": 916,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/bluenviron/gortsplib/v5/pkg/auth\"\n\t\"github.com/bluenviron/m"
},
{
"path": "internal/conf/rtsp_auth_methods.go",
"chars": 686,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\n\t\"github.com/bluenviron/gortsplib/v5/pkg/auth\"\n\t\"github.com/bluenvir"
},
{
"path": "internal/conf/rtsp_range_type.go",
"chars": 947,
"preview": "package conf\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n)\n\n// RTSPRangeType is the ty"
},
{
"path": "internal/conf/rtsp_transport.go",
"chars": 1340,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/bluenviron/gortsplib/v5\"\n\t\"github.com/bluenviron/mediamtx/i"
},
{
"path": "internal/conf/rtsp_transports.go",
"chars": 1397,
"preview": "package conf\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/bluenviron/gortsplib/v5\"\n\t\"github.com/bl"
},
{
"path": "internal/conf/string_size.go",
"chars": 801,
"preview": "package conf\n\nimport (\n\t\"code.cloudfoundry.org/bytefmt\"\n\t\"github.com/bluenviron/mediamtx/internal/conf/jsonwrapper\"\n)\n\n/"
},
{
"path": "internal/conf/webrtc_ice_server.go",
"chars": 234,
"preview": "package conf\n\n// WebRTCICEServer is a WebRTC ICE Server.\ntype WebRTCICEServer struct {\n\tURL string `json:\"url\"`\n\t"
},
{
"path": "internal/conf/yamlwrapper/testdata/fuzz/FuzzUnmarshal/90b5d1b18dd9f8ac",
"chars": 29,
"preview": "go test fuzz v1\n[]byte(\"*0\")\n"
},
{
"path": "internal/conf/yamlwrapper/testdata/fuzz/FuzzUnmarshal/dc806ec658c460fc",
"chars": 30,
"preview": "go test fuzz v1\n[]byte(\"...\")\n"
},
{
"path": "internal/conf/yamlwrapper/unmarshal.go",
"chars": 2280,
"preview": "// Package yamlwrapper contains a YAML unmarshaler.\npackage yamlwrapper\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/"
},
{
"path": "internal/conf/yamlwrapper/unmarshal_test.go",
"chars": 1572,
"preview": "package yamlwrapper\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestUnmarshalIntegerMapKey(t *t"
},
{
"path": "internal/confwatcher/confwatcher.go",
"chars": 2502,
"preview": "// Package confwatcher contains a configuration watcher.\npackage confwatcher\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"time\"\n\n\t"
},
{
"path": "internal/confwatcher/confwatcher_test.go",
"chars": 2671,
"preview": "package confwatcher\n\nimport (\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/mediamtx/internal/test\"\n\t\"github.com/str"
},
{
"path": "internal/core/api_test.go",
"chars": 48063,
"preview": "//nolint:dupl,lll\npackage core\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"net/http\"\n\t"
},
{
"path": "internal/core/core.go",
"chars": 33327,
"preview": "// Package core contains the main struct of the software.\npackage core\n\nimport (\n\t\"context\"\n\t_ \"embed\"\n\t\"fmt\"\n\t\"os\"\n\t\"os"
},
{
"path": "internal/core/core_test.go",
"chars": 2961,
"preview": "package core\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/gortsplib/v5\"\n\t\"github.com/blu"
},
{
"path": "internal/core/metrics_test.go",
"chars": 30268,
"preview": "package core\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n"
},
{
"path": "internal/core/path.go",
"chars": 27762,
"preview": "package core\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"strconv\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/bluenviron/gorts"
},
{
"path": "internal/core/path_manager.go",
"chars": 16439,
"preview": "package core\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"maps\"\n\t\"sort\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"github.com/bluenviron/mediamtx/intern"
},
{
"path": "internal/core/path_manager_test.go",
"chars": 5879,
"preview": "package core\n\nimport (\n\t\"net/http\"\n\t\"regexp\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/bluenviron/gortsplib/v5\"\n\t\"github.com/blue"
},
{
"path": "internal/core/path_test.go",
"chars": 26214,
"preview": "package core\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"s"
},
{
"path": "internal/core/source_redirect.go",
"chars": 468,
"preview": "package core\n\nimport (\n\t\"github.com/bluenviron/mediamtx/internal/defs\"\n\t\"github.com/bluenviron/mediamtx/internal/logger\""
},
{
"path": "internal/core/test_on_demand/main.go",
"chars": 1206,
"preview": "// This is used for testing purposes.\npackage main\n\nimport (\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\n\t\"github.com/bluenviron/gort"
},
{
"path": "internal/core/upgrade.go",
"chars": 3667,
"preview": "//go:build enable_upgrade\n\npackage core\n\nimport (\n\t\"archive/tar\"\n\t\"archive/zip\"\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"fmt\"\n\t\"io\"\n\t"
},
{
"path": "internal/core/upgrade_disabled.go",
"chars": 136,
"preview": "//go:build !enable_upgrade\n\npackage core\n\nimport \"fmt\"\n\nfunc upgrade() error {\n\treturn fmt.Errorf(\"upgrade command is no"
},
{
"path": "internal/core/versiongetter/main.go",
"chars": 3485,
"preview": "// Package main contains an utility to get the server version\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath"
},
{
"path": "internal/counterdumper/dumper.go",
"chars": 1405,
"preview": "// Package counterdumper contains a counter that that periodically invokes a callback if the counter is not zero.\npackag"
},
{
"path": "internal/counterdumper/dumper_test.go",
"chars": 604,
"preview": "package counterdumper\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestDumperReport(t *t"
},
{
"path": "internal/defs/api.go",
"chars": 935,
"preview": "package defs\n\nimport (\n\t\"time\"\n\n\t\"github.com/bluenviron/mediamtx/internal/conf\"\n)\n\n// APIOKStatus is the status of a suc"
},
{
"path": "internal/defs/api_hls.go",
"chars": 836,
"preview": "package defs\n\nimport \"time\"\n\n// APIHLSServer contains methods used by the API and Metrics server.\ntype APIHLSServer inte"
},
{
"path": "internal/defs/api_path.go",
"chars": 3751,
"preview": "package defs\n\nimport (\n\t\"time\"\n)\n\n// APIPathManager contains methods used by the API and Metrics server.\ntype APIPathMan"
},
{
"path": "internal/defs/api_path_track.go",
"chars": 176,
"preview": "package defs\n\n// APIPathTrack is a track.\ntype APIPathTrack struct {\n\tCodec APIPathTrackCodec `json:\"codec\"`\n\t"
}
]
// ... and 273 more files (download for full content)
About this extraction
This page contains the full source code of the bluenviron/mediamtx GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 473 files (1.9 MB), approximately 614.2k tokens, and a symbol index with 2116 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.