Skip to content

Commit

Permalink
Merge pull request #388 from cordova-rtc/task/remove-src-video-blob
Browse files Browse the repository at this point in the history
Deprecate usage of 'video.src = URL.createObjectURL(stream)' in favor…
  • Loading branch information
hthetiot committed Sep 17, 2019
2 parents 71f26e8 + 57a202c commit 9ed1234
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 135 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
#### Version 5.0.3

* Deprecate usage of `video.src = URL.createObjectURL(stream)` in favor of `video.srcObject = stream` only MediaStream are not Blob anymore.

#### Version 5.0.2

* Set default deployment target to 10.2
* Remove callback based API
* Implement RTCPeerConnection.getSenders|getReceivers|addTrack|removeTrack
Expand All @@ -12,6 +17,7 @@
* fix TypeError: undefined is not an object (evaluating 'stream.id') when removing stream [PR #383](https://github.com/cordova-rtc/cordova-plugin-iosrtc/pull/383) by @hthetiot via @l7s).

#### Version 5.0.1

* fix typo on iosrtcPlugin.swift

#### Version 5.0.0
Expand Down
2 changes: 1 addition & 1 deletion FAQ.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# FAQ

**Q:** What about `<video>` elements and `video.src = URL.createObjectURL(stream)`? do I need custom HTML tags or functions to display WebRTC videos?
**Q:** What about `<video>` elements and `video.srcObject = stream`? do I need custom HTML tags or functions to display WebRTC videos?

**A:** No. Just use an HTML video element as usual, really. The plugin will properly place a native *UIView* layer on top of it by respecting (most of) its [CSS properties](docs/videoCSS.md).

Expand Down
74 changes: 7 additions & 67 deletions dist/cordova-plugin-iosrtc.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ var originalMediaStreamTrack = MediaStreamTrack.originalMediaStreamTrack;

/**
* Expose the MediaStream class.
* Make MediaStream be a Blob so it can be consumed by URL.createObjectURL().
*/
function MediaStream(arg, id) {
debug('new MediaStream(arg) | [arg:%o]', arg);
Expand Down Expand Up @@ -2470,7 +2469,6 @@ function dump() {

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./MediaStream":4,"./MediaStreamTrack":6,"./RTCIceCandidate":9,"./RTCPeerConnection":10,"./RTCSessionDescription":11,"./enumerateDevices":14,"./getUserMedia":15,"./videoElementsHandler":17,"cordova/exec":undefined,"debug":18,"domready":20}],17:[function(_dereq_,module,exports){
(function (global){
/**
* Expose a function that must be called when the library is loaded.
* And also a helper function.
Expand All @@ -2491,12 +2489,6 @@ var
* Local variables.
*/

// RegExp for MediaStream blobId.
MEDIASTREAM_ID_REGEXP = new RegExp(/^MediaStream_/),

// RegExp for Blob URI.
BLOB_URI_REGEX = new RegExp(/^blob:/),

// Dictionary of MediaStreamRenderers (provided via module argument).
// - key: MediaStreamRenderer id.
// - value: MediaStreamRenderer.
Expand All @@ -2517,8 +2509,8 @@ var
// HTML video element.
video = mutation.target;

// .src or .srcObject removed.
if (!video.src && !video.srcObject) {
// .srcObject removed.
if (!video.srcObject) {
// If this video element was previously handling a MediaStreamRenderer, release it.
releaseMediaStreamRenderer(video);
continue;
Expand Down Expand Up @@ -2643,13 +2635,13 @@ function videoElementsHandler(_mediaStreams, _mediaStreamRenderers) {
function observeVideo(video) {
debug('observeVideo()');

// If the video already has a src/srcObject property but is not yet handled by the plugin
// If the video already has a srcObject property but is not yet handled by the plugin
// then handle it now.
if ((video.src || video.srcObject) && !video._iosrtcMediaStreamRendererId) {
if ((video.srcObject) && !video._iosrtcMediaStreamRendererId) {
handleVideo(video);
}

// Add .src observer to the video element.
// Add .srcObject observer to the video element.
videoObserver.observe(video, {
// Set to true if additions and removals of the target node's child elements (including text
// nodes) are to be observed.
Expand All @@ -2668,16 +2660,7 @@ function observeVideo(video) {
characterDataOldValue: false,
// Set to an array of attribute local names (without namespace) if not all attribute mutations
// need to be observed.
attributeFilter: ['src', 'srcObject']
});

// Intercept video 'error' events if it's due to the attached MediaStream.
video.addEventListener('error', function (event) {
if (video.error.code === global.MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED && BLOB_URI_REGEX.test(video.src)) {
debug('stopping "error" event propagation for video element');

event.stopImmediatePropagation();
}
attributeFilter: ['srcObject']
});
}

Expand All @@ -2688,51 +2671,10 @@ function observeVideo(video) {

function handleVideo(video) {
var
xhr = new XMLHttpRequest(),
stream;

// The app has set video.src.
if (video.src) {
xhr.open('GET', video.src, true);
xhr.responseType = 'blob';
xhr.onload = function () {
if (xhr.status !== 200) {
// If this video element was previously handling a MediaStreamRenderer, release it.
releaseMediaStreamRenderer(video);

return;
}

var reader = new FileReader();

// Some versions of Safari fail to set onloadend property, some others do not react
// on 'loadend' event. Try everything here.
try {
reader.onloadend = onloadend;
} catch (error) {
reader.addEventListener('loadend', onloadend);
}
reader.readAsText(xhr.response);

function onloadend() {
var mediaStreamBlobId = reader.result;

// The retrieved URL does not point to a MediaStream.
if (!mediaStreamBlobId || typeof mediaStreamBlobId !== 'string' || !MEDIASTREAM_ID_REGEXP.test(mediaStreamBlobId)) {
// If this video element was previously handling a MediaStreamRenderer, release it.
releaseMediaStreamRenderer(video);

return;
}

provideMediaStreamRenderer(video, mediaStreamBlobId);
}
};
xhr.send();
}

// The app has set video.srcObject.
else if (video.srcObject) {
if (video.srcObject) {
stream = video.srcObject;

if (!stream.getBlobId()) {
Expand Down Expand Up @@ -2805,7 +2747,6 @@ function provideMediaStreamRenderer(video, mediaStreamBlobId) {
});
}


function releaseMediaStreamRenderer(video) {
if (!video._iosrtcMediaStreamRendererId) {
return;
Expand All @@ -2826,7 +2767,6 @@ function releaseMediaStreamRenderer(video) {
delete video.readyState;
}

}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./MediaStreamRenderer":5,"debug":18}],18:[function(_dereq_,module,exports){
(function (process){
/* eslint-env browser */
Expand Down
2 changes: 1 addition & 1 deletion docs/iosrtc.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ peerconnection.addEventListener('addstream', function (event) {
cordova.plugins.iosrtc.observeVideo(video);

// Attach the MediaStream to it.
video.src = URL.createObjectURL(event.stream);
video.srcObject = event.stream;

// When the stream is ready to be rendered then append the video
// element to the DOM.
Expand Down
1 change: 0 additions & 1 deletion extra/renderer-and-libwebrtc-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ function TestGetUserMedia() {

localStream = stream;
srcObjectStream = localVideoEl.srcObject = localStream;
//localVideoEl.src = window.URL.createObjectURL(stream);

} catch (err) {
console.log('srcObject.err', err);
Expand Down
1 change: 0 additions & 1 deletion js/MediaStream.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ var originalMediaStreamTrack = MediaStreamTrack.originalMediaStreamTrack;

/**
* Expose the MediaStream class.
* Make MediaStream be a Blob so it can be consumed by URL.createObjectURL().
*/
function MediaStream(arg, id) {
debug('new MediaStream(arg) | [arg:%o]', arg);
Expand Down
71 changes: 7 additions & 64 deletions js/videoElementsHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,6 @@ var
* Local variables.
*/

// RegExp for MediaStream blobId.
MEDIASTREAM_ID_REGEXP = new RegExp(/^MediaStream_/),

// RegExp for Blob URI.
BLOB_URI_REGEX = new RegExp(/^blob:/),

// Dictionary of MediaStreamRenderers (provided via module argument).
// - key: MediaStreamRenderer id.
// - value: MediaStreamRenderer.
Expand All @@ -44,8 +38,8 @@ var
// HTML video element.
video = mutation.target;

// .src or .srcObject removed.
if (!video.src && !video.srcObject) {
// .srcObject removed.
if (!video.srcObject) {
// If this video element was previously handling a MediaStreamRenderer, release it.
releaseMediaStreamRenderer(video);
continue;
Expand Down Expand Up @@ -170,13 +164,13 @@ function videoElementsHandler(_mediaStreams, _mediaStreamRenderers) {
function observeVideo(video) {
debug('observeVideo()');

// If the video already has a src/srcObject property but is not yet handled by the plugin
// If the video already has a srcObject property but is not yet handled by the plugin
// then handle it now.
if ((video.src || video.srcObject) && !video._iosrtcMediaStreamRendererId) {
if ((video.srcObject) && !video._iosrtcMediaStreamRendererId) {
handleVideo(video);
}

// Add .src observer to the video element.
// Add .srcObject observer to the video element.
videoObserver.observe(video, {
// Set to true if additions and removals of the target node's child elements (including text
// nodes) are to be observed.
Expand All @@ -195,16 +189,7 @@ function observeVideo(video) {
characterDataOldValue: false,
// Set to an array of attribute local names (without namespace) if not all attribute mutations
// need to be observed.
attributeFilter: ['src', 'srcObject']
});

// Intercept video 'error' events if it's due to the attached MediaStream.
video.addEventListener('error', function (event) {
if (video.error.code === global.MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED && BLOB_URI_REGEX.test(video.src)) {
debug('stopping "error" event propagation for video element');

event.stopImmediatePropagation();
}
attributeFilter: ['srcObject']
});
}

Expand All @@ -215,51 +200,10 @@ function observeVideo(video) {

function handleVideo(video) {
var
xhr = new XMLHttpRequest(),
stream;

// The app has set video.src.
if (video.src) {
xhr.open('GET', video.src, true);
xhr.responseType = 'blob';
xhr.onload = function () {
if (xhr.status !== 200) {
// If this video element was previously handling a MediaStreamRenderer, release it.
releaseMediaStreamRenderer(video);

return;
}

var reader = new FileReader();

// Some versions of Safari fail to set onloadend property, some others do not react
// on 'loadend' event. Try everything here.
try {
reader.onloadend = onloadend;
} catch (error) {
reader.addEventListener('loadend', onloadend);
}
reader.readAsText(xhr.response);

function onloadend() {
var mediaStreamBlobId = reader.result;

// The retrieved URL does not point to a MediaStream.
if (!mediaStreamBlobId || typeof mediaStreamBlobId !== 'string' || !MEDIASTREAM_ID_REGEXP.test(mediaStreamBlobId)) {
// If this video element was previously handling a MediaStreamRenderer, release it.
releaseMediaStreamRenderer(video);

return;
}

provideMediaStreamRenderer(video, mediaStreamBlobId);
}
};
xhr.send();
}

// The app has set video.srcObject.
else if (video.srcObject) {
if (video.srcObject) {
stream = video.srcObject;

if (!stream.getBlobId()) {
Expand Down Expand Up @@ -332,7 +276,6 @@ function provideMediaStreamRenderer(video, mediaStreamBlobId) {
});
}


function releaseMediaStreamRenderer(video) {
if (!video._iosrtcMediaStreamRendererId) {
return;
Expand Down

0 comments on commit 9ed1234

Please sign in to comment.