- 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