- From: guest271314 via GitHub <sysbot+gh@w3.org>
- Date: Mon, 02 Dec 2019 06:10:34 +0000
- To: public-webrtc-logs@w3.org
Load this plnkr https://plnkr.co/edit/Axkb8s?preview&p=preview, substitute the below HTML for index.html. Run the code at least twice to 10 times in succession.
At Chromium 80
Expected output (result of `MediaRecorder` recording `MediaStream` from WebRTC)
```
resulting video resize 768 576
resulting video resize 480 240
resulting video resize 640 360
resulting video resize 400 300
resulting video resize 1280 720
```
occasional output
```
resulting video resize 288 216
resulting video resize 384 288
resulting video resize 480 240
resulting video resize 640 360
resulting video resize 400 300
resulting video resize 1280 720
```
At Firefox 70, Nightly 72 the code requires changing to an appreciable degree due to lack of full support for `AudioWorklet`. Occasionally the output at Firefox, Nightly will also have unexpected values
```
720 576
480 240
640 360
400 300
1280 720
```
```
<!DOCTYPE html>
<html>
<head>
<title>
Record MediaStream potentially including variable width and height
MediaStreamTrack
</title>
</head>
<body>
<video id="video" autoplay controls></video>
<script type="module">
// MediaStream outputting #000000 video frames and audio silence
import { mediaStream, audioContext, worker } from './export.js';
let recorder, result;
const videoStream = document.getElementById('video');
console.log(mediaStream, audioContext, worker);
(async () => {
let handleChromiumVideoElementMediaRecorderBug;
const [audioTrack, videoTrack] = ['audio', 'video'].map(kind =>
mediaStream
.getTracks()
.find(({ kind: trackKind }) => trackKind === kind)
);
const fromLocalPeerConnection = new RTCPeerConnection({sdpSemantics:"unified-plan"});
const toLocalPeerConnection = new RTCPeerConnection({sdpSemantics:"unified-plan"});
const fromConnection = new Promise(resolve =>
fromLocalPeerConnection.addEventListener(
'icecandidate',
async e => {
console.log('from', e);
try {
resolve(
toLocalPeerConnection.addIceCandidate(
e.candidate ? e.candidate : null
)
);
} catch (e) {
console.error(e);
}
},
{
once: true,
}
)
);
const toConnection = new Promise(resolve =>
toLocalPeerConnection.addEventListener(
'icecandidate',
async e => {
console.log('to', e);
try {
resolve(
fromLocalPeerConnection.addIceCandidate(
e.candidate ? e.candidate : null
)
);
} catch (e) {
console.error(e);
}
},
{
once: true,
}
)
);
fromLocalPeerConnection.addEventListener('negotiationneeded', e => {
console.log(e);
});
toLocalPeerConnection.addEventListener('negotiationneeded', e => {
console.log(e);
});
let tracks = new Promise(resolve => {
let ids = mediaStream.getTracks().map(({ id }) => id),
i = 0;
toLocalPeerConnection.addEventListener(
'track',
({ track, streams: [stream] }) => {
if (ids.includes(track.id) && ++i === ids.length) {
resolve(stream);
}
}
);
});
// Add initial audio and video MediaStreamTrack to PeerConnection, pass initial MediaStream
const {
sender: audioSender,
receiver: audioReceiver,
} = fromLocalPeerConnection.addTransceiver(audioTrack, {
streams: [mediaStream],
});
const {
sender: videoSender,
receiver: videoReceiver,
} = fromLocalPeerConnection.addTransceiver(videoTrack, {
streams: [mediaStream],
});
console.log(audioSender, videoSender, audioReceiver, videoReceiver);
const offer = await fromLocalPeerConnection.createOffer();
await toLocalPeerConnection.setRemoteDescription(offer);
await fromLocalPeerConnection.setLocalDescription(
toLocalPeerConnection.remoteDescription
);
const answer = await toLocalPeerConnection.createAnswer();
await fromLocalPeerConnection.setRemoteDescription(answer);
await toLocalPeerConnection.setLocalDescription(
fromLocalPeerConnection.remoteDescription
);
const stream = await tracks;
// video.srcObject = stream;
// When MediaStream is not set as srcObject Blob at MediaRecorder
// dataavailable event size is 0
const urls = await Promise.all(
[
{
src:
'https://upload.wikimedia.org/wikipedia/commons/a/a4/Xacti-AC8EX-Sample_video-001.ogv',
from: 0,
to: 4,
},
{
src:
'https://mirrors.creativecommons.org/movingimages/webm/ScienceCommonsJesseDylan_240p.webm#t=10,20',
from: 10,
to: 20,
},
{
from: 55,
to: 60,
src:
'https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4',
},
{
from: 0,
to: 5,
src:
'https://raw.githubusercontent.com/w3c/web-platform-tests/master/media-source/mp4/test.mp4',
},
{
from: 0,
to: 5,
src:
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4',
},
{
from: 0,
to: 5,
src:
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4',
},
{
from: 0,
to: 6,
src:
'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerMeltdowns.mp4#t=0,6',
},
].map(async ({ from, to, src }) => {
try {
const request = await fetch(src);
const blob = await request.blob();
const blobURL = URL.createObjectURL(blob);
const url = new URL(src);
console.log(url.hash);
return blobURL + (url.hash || `#t=${from},${to}`);
} catch (e) {
throw e;
}
})
);
//const videoStream = document.createElement("video");
videoStream.muted = true;
videoStream.onresize = e =>
console.log(
e.type,
'every resize',
e.target.videoWidth,
e.target.videoHeight
);
videoStream.onloadedmetadata = e => {
const { videoWidth, videoHeight } = e.target;
console.log(e.type, videoWidth, videoHeight);
};
const ms = videoStream.captureStream();
ms.onaddtrack = async e => {
if (e.track.kind === 'audio') {
await audioSender.replaceTrack(e.track);
} else {
await videoSender.replaceTrack(e.track);
console.log(e.track.getSettings());
}
};
for (const blobURL of urls) {
await new Promise(resolve => {
videoStream.addEventListener(
'pause',
async _ => {
resolve();
},
{
once: true,
}
);
videoStream.addEventListener(
'canplay',
async _ => {
if (!recorder) {
tracks = await tracks;
handleChromiumVideoElementMediaRecorderBug = document.createElement("video").srcObject = tracks;
recorder = new MediaRecorder(tracks, {
mimeType: 'video/webm',
});
recorder.onstart = _ => {
console.log(_.type);
};
result = new Promise(resolve => {
recorder.addEventListener(
'dataavailable',
({ data }) => {
resolve(data);
},
{
once: true,
}
);
});
recorder.start();
}
await videoStream.play();
},
{
once: true,
}
);
videoStream.src = blobURL;
});
}
recorder.stop();
let blob = await result;
let blobURL = URL.createObjectURL(blob);
console.log(blob);
await audioContext.close();
worker.terminate();
[mediaStream.getTracks(), stream.getTracks(), ms.getTracks()]
.flat()
.forEach(track => {
track.enabled = false;
track.stop();
console.log(track);
});
video.srcObject = null;
video.remove();
videoStream.src = '';
videoStream.remove();
const recordedVideo = document.createElement('video');
document.body.appendChild(recordedVideo);
recordedVideo.autoplay = recordedVideo.controls = true;
recordedVideo.onresize = ({ target: { videoWidth, videoHeight } }) => {
console.log("resulting video resize", videoWidth, videoHeight);
};
recordedVideo.src = blobURL;
})();
</script>
</body>
</html>
```
--
GitHub Notification of comment by guest271314
Please view or discuss this issue at https://github.com/w3c/mediacapture-main/issues/647#issuecomment-560247873 using your GitHub account
Received on Monday, 2 December 2019 06:10:36 UTC