Player: Get codec by webrtc api: pc.getStats. v7.0.42 (#4310)

1. It cannot retrieve codec information on `Firefox` by
`getSenders/getReceivers`
2. It can retrieve codec information on `Chrome` by `getReceivers`, but
incorrect, like this:

![image](https://github.com/user-attachments/assets/e0bb93b1-ccd0-46c0-ae21-074934f66a1e)

3. So, we retrieve codec information from `getStats`, and it works well.
4. The timer is used because sometimes the codec cannot be retrieved
when `iceGatheringState` is `complete`.
5. Testing has been completed on the browsers listed below.
   - [x] Chrome
   - [x] Edge
   - [x] Safari
   - [x] Firefox

---------

Co-authored-by: winlin <winlinvip@gmail.com>
This commit is contained in:
Haibo Chen(陈海博) 2025-06-04 22:28:46 +08:00 committed by GitHub
parent 133866a944
commit 07e7984fdf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 65 additions and 30 deletions

View File

@ -7,6 +7,7 @@ The changelog for SRS.
<a name="v7-changes"></a>
## SRS 7.0 Changelog
* v7.0, 2025-06-04, Merge [#4310](https://github.com/ossrs/srs/pull/4310): Player: Get codec by webrtc api: pc.getStats. v7.0.42 (#4310)
* v7.0, 2025-06-04, Merge [#4325](https://github.com/ossrs/srs/pull/4325): fix bug: loop transcoding #3516. v7.0.41 (#4325)
* v7.0, 2025-06-04, Merge [#4341](https://github.com/ossrs/srs/pull/4341): Update the release in the README for consistent. v7.0.40 (#4341)
* v7.0, 2025-06-04, Merge [#4368](https://github.com/ossrs/srs/pull/4368): Update the codename for version 7.0 to "Kai". v7.0.39 (#4368)

View File

@ -686,33 +686,29 @@ function SrsRtcWhipWhepAsync() {
return self;
}
// Format the codec of RTCRtpSender, kind(audio/video) is optional filter.
// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/WebRTC_codecs#getting_the_supported_codecs
function SrsRtcFormatSenders(senders, kind) {
// https://developer.mozilla.org/en-US/docs/Web/API/RTCStatsReport
function SrsRtcFormatStats(stats, kind) {
var codecs = [];
senders.forEach(function (sender) {
var params = sender.getParameters();
params && params.codecs && params.codecs.forEach(function(c) {
if (kind && sender.track.kind !== kind) {
return;
}
if (c.mimeType.indexOf('/red') > 0 || c.mimeType.indexOf('/rtx') > 0 || c.mimeType.indexOf('/fec') > 0) {
return;
}
stats.forEach((report) => {
if (report.type === 'codec' && report.mimeType?.toLowerCase().startsWith(kind)) {
var s = '';
s += c.mimeType.replace('audio/', '').replace('video/', '');
s += ', ' + c.clockRate + 'HZ';
if (sender.track.kind === "audio") {
s += ', channels: ' + c.channels;
s += report.mimeType.split('/')[1] || report.mimeType;
if (report.clockRate) {
s += ', ' + report.clockRate + 'HZ';
}
s += ', pt: ' + c.payloadType;
if (kind === 'audio' && report.channels) {
s += ', channels: ' + report.channels;
}
if (report.payloadType) {
s += ', pt: ' + report.payloadType;
}
codecs.push(s);
});
}
});
return codecs.join(", ");
}
}

View File

@ -71,6 +71,10 @@
SessionID: <span id='sessionid'></span>
<p></p>
Audio: <span id='acodecs'></span><br/>
Video: <span id='vcodecs'></span>
<p></p>
Simulator: <a href='#' id='simulator-drop'>Drop</a>
@ -82,9 +86,14 @@
<script type="text/javascript">
$(function(){
var sdk = null; // Global handler to do cleanup when republishing.
var statsTimer = null;
var startPlay = function() {
$('#rtc_media_player').show();
if (statsTimer) {
clearInterval(statsTimer);
}
// Close PC when user replay.
if (sdk) {
sdk.close();
@ -97,6 +106,22 @@ $(function(){
// Optional callback, SDK will add track to stream.
// sdk.ontrack = function (event) { console.log('Got track', event); sdk.stream.addTrack(event.track); };
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/getStats
statsTimer = setInterval(() => {
sdk.pc.getStats(null).then((stats) => {
let audioStatsOutput = SrsRtcFormatStats(stats, 'audio');
let videoStatsOutput = SrsRtcFormatStats(stats, 'video');
document.querySelector("#acodecs").innerHTML = audioStatsOutput;
document.querySelector("#vcodecs").innerHTML = videoStatsOutput;
if (audioStatsOutput && videoStatsOutput) {
clearInterval(statsTimer);
console.log('Stats detected, stopping stats timer');
}
});
}, 1000);
// For example: webrtc://r.ossrs.net/live/livestream
var url = $("#txt_url").val();
sdk.play(url, {

View File

@ -93,9 +93,14 @@
<script type="text/javascript">
$(function(){
var sdk = null; // Global handler to do cleanup when republishing.
var statsTimer = null;
var startPublish = function() {
$('#rtc_media_player').show();
if (statsTimer) {
clearInterval(statsTimer);
}
// Close PC when user replay.
if (sdk) {
sdk.close();
@ -108,13 +113,21 @@ $(function(){
// Optional callback, SDK will add track to stream.
// sdk.ontrack = function (event) { console.log('Got track', event); sdk.stream.addTrack(event.track); };
// https://developer.mozilla.org/en-US/docs/Web/Media/Formats/WebRTC_codecs#getting_the_supported_codecs
sdk.pc.onicegatheringstatechange = function (event) {
if (sdk.pc.iceGatheringState === "complete") {
$('#acodecs').html(SrsRtcFormatSenders(sdk.pc.getSenders(), "audio"));
$('#vcodecs').html(SrsRtcFormatSenders(sdk.pc.getSenders(), "video"));
}
};
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/getStats
statsTimer = setInterval(() => {
sdk.pc.getStats(null).then((stats) => {
let audioStatsOutput = SrsRtcFormatStats(stats, 'audio');
let videoStatsOutput = SrsRtcFormatStats(stats, 'video');
document.querySelector("#acodecs").innerHTML = audioStatsOutput;
document.querySelector("#vcodecs").innerHTML = videoStatsOutput;
if (audioStatsOutput && videoStatsOutput) {
clearInterval(statsTimer);
console.log('Stats detected, stopping stats timer');
}
});
}, 1000);
// For example: webrtc://r.ossrs.net/live/livestream
var url = $("#txt_url").val();

View File

@ -9,6 +9,6 @@
#define VERSION_MAJOR 7
#define VERSION_MINOR 0
#define VERSION_REVISION 41
#define VERSION_REVISION 42
#endif