mirror of
https://github.com/ossrs/srs.git
synced 2025-11-23 19:34:05 +08:00
AI: WebRTC: Fix camera/microphone not released after closing publisher. v7.0.106 (#4261)
This commit is contained in:
@@ -7,9 +7,10 @@ The changelog for SRS.
|
||||
<a name="v7-changes"></a>
|
||||
|
||||
## SRS 7.0 Changelog
|
||||
* v7.0, 2025-10-26, Build: Improve dependency checking to report all missing dependencies at once. v7.0.105 (#4293)
|
||||
* v7.0, 2025-10-26, HLS: Support hls_master_m3u8_path_relative for reverse proxy compatibility. v7.0.104 (#4338)
|
||||
* v7.0, 2025-10-25, API: Remove minimum limit of 10 for count parameter in /api/v1/streams and /api/v1/clients. v7.0.103 (#4358)
|
||||
* v7.0, 2025-10-26, AI: WebRTC: Fix camera/microphone not released after closing publisher. v7.0.106 (#4261)
|
||||
* v7.0, 2025-10-26, AI: Build: Improve dependency checking to report all missing dependencies at once. v7.0.105 (#4293)
|
||||
* v7.0, 2025-10-26, AI: HLS: Support hls_master_m3u8_path_relative for reverse proxy compatibility. v7.0.104 (#4338)
|
||||
* v7.0, 2025-10-25, AI: API: Remove minimum limit of 10 for count parameter in /api/v1/streams and /api/v1/clients. v7.0.103 (#4358)
|
||||
* v7.0, 2025-10-22, AI: Only support AAC/MP3/Opus audio codec. v7.0.102 (#4516)
|
||||
* v7.0, 2025-10-22, AI: Fix AAC audio sample rate reporting in API. v7.0.101 (#4518)
|
||||
* v7.0, 2025-10-20, Merge [#4537](https://github.com/ossrs/srs/pull/4537): Forward: Reject RTMPS destinations with clear error message. v7.0.100 (#4537)
|
||||
|
||||
@@ -28,6 +28,9 @@ function SrsRtcPublisherAsync() {
|
||||
}
|
||||
};
|
||||
|
||||
// Store media stream to stop tracks when closing.
|
||||
self.userStream = null;
|
||||
|
||||
// @see https://github.com/rtcdn/rtcdn-draft
|
||||
// @url The WebRTC url to play with, for example:
|
||||
// webrtc://r.ossrs.net/live/livestream
|
||||
@@ -60,10 +63,10 @@ function SrsRtcPublisherAsync() {
|
||||
if (!navigator.mediaDevices && window.location.protocol === 'http:' && window.location.hostname !== 'localhost') {
|
||||
throw new SrsError('HttpsRequiredError', `Please use HTTPS or localhost to publish, read https://github.com/ossrs/srs/issues/2762#issuecomment-983147576`);
|
||||
}
|
||||
var stream = await navigator.mediaDevices.getUserMedia(self.constraints);
|
||||
self.userStream = await navigator.mediaDevices.getUserMedia(self.constraints);
|
||||
|
||||
// @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addStream#Migrating_to_addTrack
|
||||
stream.getTracks().forEach(function (track) {
|
||||
self.userStream.getTracks().forEach(function (track) {
|
||||
self.pc.addTrack(track);
|
||||
|
||||
// Notify about local track when stream is ok.
|
||||
@@ -104,6 +107,14 @@ function SrsRtcPublisherAsync() {
|
||||
self.close = function () {
|
||||
self.pc && self.pc.close();
|
||||
self.pc = null;
|
||||
|
||||
// Stop all media tracks to release camera/microphone.
|
||||
if (self.userStream) {
|
||||
self.userStream.getTracks().forEach(function (track) {
|
||||
track.stop();
|
||||
});
|
||||
self.userStream = null;
|
||||
}
|
||||
};
|
||||
|
||||
// The callback when got local stream.
|
||||
@@ -523,6 +534,10 @@ function SrsRtcWhipWhepAsync() {
|
||||
}
|
||||
};
|
||||
|
||||
// Store media streams to stop tracks when closing.
|
||||
self.displayStream = null;
|
||||
self.userStream = null;
|
||||
|
||||
// See https://datatracker.ietf.org/doc/draft-ietf-wish-whip/
|
||||
// @url The WebRTC url to publish with, for example:
|
||||
// http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream
|
||||
@@ -557,11 +572,11 @@ function SrsRtcWhipWhepAsync() {
|
||||
}
|
||||
|
||||
if (useScreen) {
|
||||
const displayStream = await navigator.mediaDevices.getDisplayMedia({
|
||||
self.displayStream = await navigator.mediaDevices.getDisplayMedia({
|
||||
video: true
|
||||
});
|
||||
// @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addStream#Migrating_to_addTrack
|
||||
displayStream.getTracks().forEach(function (track) {
|
||||
self.displayStream.getTracks().forEach(function (track) {
|
||||
self.pc.addTrack(track);
|
||||
// Notify about local track when stream is ok.
|
||||
self.ontrack && self.ontrack({track: track});
|
||||
@@ -569,9 +584,9 @@ function SrsRtcWhipWhepAsync() {
|
||||
}
|
||||
|
||||
if (useCamera || hasAudio) {
|
||||
const userStream = await navigator.mediaDevices.getUserMedia(self.constraints);
|
||||
self.userStream = await navigator.mediaDevices.getUserMedia(self.constraints);
|
||||
|
||||
userStream.getTracks().forEach(function (track) {
|
||||
self.userStream.getTracks().forEach(function (track) {
|
||||
self.pc.addTrack(track);
|
||||
// Notify about local track when stream is ok.
|
||||
self.ontrack && self.ontrack({track: track});
|
||||
@@ -643,6 +658,20 @@ function SrsRtcWhipWhepAsync() {
|
||||
self.close = function () {
|
||||
self.pc && self.pc.close();
|
||||
self.pc = null;
|
||||
|
||||
// Stop all media tracks to release camera/microphone.
|
||||
if (self.displayStream) {
|
||||
self.displayStream.getTracks().forEach(function (track) {
|
||||
track.stop();
|
||||
});
|
||||
self.displayStream = null;
|
||||
}
|
||||
if (self.userStream) {
|
||||
self.userStream.getTracks().forEach(function (track) {
|
||||
track.stop();
|
||||
});
|
||||
self.userStream = null;
|
||||
}
|
||||
};
|
||||
|
||||
// The callback when got local stream.
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
URL:
|
||||
<input type="text" id="txt_url" class="input-xxlarge" value="">
|
||||
<button class="btn btn-primary" id="btn_play">Play</button>
|
||||
<button class="btn btn-danger" id="btn_stop" disabled>Stop</button>
|
||||
</div>
|
||||
|
||||
<p></p>
|
||||
@@ -130,6 +131,9 @@ $(function(){
|
||||
}).then(function(session){
|
||||
$('#sessionid').html(session.sessionid);
|
||||
$('#simulator-drop').attr('href', session.simulator + '?drop=1&username=' + session.sessionid);
|
||||
// Enable stop button after successful play
|
||||
$('#btn_stop').prop('disabled', false);
|
||||
$('#btn_play').prop('disabled', true);
|
||||
}).catch(function (reason) {
|
||||
sdk.close();
|
||||
$('#rtc_media_player').hide();
|
||||
@@ -137,11 +141,28 @@ $(function(){
|
||||
});
|
||||
};
|
||||
|
||||
var stopPlay = function() {
|
||||
if (sdk) {
|
||||
sdk.close();
|
||||
|
||||
if (statsTimer) {
|
||||
clearInterval(statsTimer);
|
||||
statsTimer = null;
|
||||
}
|
||||
|
||||
$('#btn_stop').prop('disabled', true);
|
||||
$('#btn_play').prop('disabled', false);
|
||||
$('#sessionid').html('(stopped)');
|
||||
$('#rtc_media_player').hide();
|
||||
}
|
||||
};
|
||||
|
||||
$('#rtc_media_player').hide();
|
||||
var query = parse_query_string();
|
||||
srs_init_whep("#txt_url", query);
|
||||
|
||||
$("#btn_play").click(startPlay);
|
||||
$("#btn_stop").click(stopPlay);
|
||||
// Never play util windows loaded @see https://github.com/ossrs/srs/issues/2732
|
||||
if (query.autostart === 'true') {
|
||||
$('#rtc_media_player').prop('muted', true);
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
URL:
|
||||
<input type="text" id="txt_url" class="input-xxlarge" value="">
|
||||
<button class="btn btn-primary" id="btn_publish">Publish</button>
|
||||
<button class="btn btn-danger" id="btn_stop" disabled>Stop</button>
|
||||
</div>
|
||||
|
||||
<p></p>
|
||||
@@ -138,6 +139,9 @@ $(function(){
|
||||
}).then(function(session){
|
||||
$('#sessionid').html(session.sessionid);
|
||||
$('#simulator-drop').attr('href', session.simulator + '?drop=1&username=' + session.sessionid);
|
||||
// Enable stop button after successful publish
|
||||
$('#btn_stop').prop('disabled', false);
|
||||
$('#btn_publish').prop('disabled', true);
|
||||
}).catch(function (reason) {
|
||||
// Throw by sdk.
|
||||
if (reason instanceof SrsError) {
|
||||
@@ -164,11 +168,29 @@ $(function(){
|
||||
});
|
||||
};
|
||||
|
||||
var stopPublish = function() {
|
||||
if (sdk) {
|
||||
sdk.close();
|
||||
|
||||
if (statsTimer) {
|
||||
clearInterval(statsTimer);
|
||||
statsTimer = null;
|
||||
}
|
||||
|
||||
$('#btn_stop').prop('disabled', true);
|
||||
$('#btn_publish').prop('disabled', false);
|
||||
$('#sessionid').html('(stopped)');
|
||||
$('#rtc_media_player').hide();
|
||||
console.log('PeerConnection closed. Check if camera indicator is still on!');
|
||||
}
|
||||
};
|
||||
|
||||
$('#rtc_media_player').hide();
|
||||
var query = parse_query_string();
|
||||
srs_init_whip("#txt_url", query);
|
||||
|
||||
$("#btn_publish").click(startPublish);
|
||||
$("#btn_stop").click(stopPublish);
|
||||
// Never play util windows loaded @see https://github.com/ossrs/srs/issues/2732
|
||||
if (query.autostart === 'true') {
|
||||
window.addEventListener("load", function(){ startPublish(); });
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
|
||||
#define VERSION_MAJOR 7
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 105
|
||||
#define VERSION_REVISION 106
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user