zoukankan      html  css  js  c++  java
  • WebRTC网页录制音视频教程

    导语:最近研究了一下网页录制音视频的原理以及实现,现在就目前的实现方法做一个总结。

    目录

    • 相关API
    • 方法介绍
    • 实战演练

    相关API

    要实现这个功能就涉及到两个js api。

    方法介绍

    getUserMedia

    通过getUserMedia这个接口来获取设备的摄像头和麦克风,返回一个Promise对象。

    语法var stream = navigator.mediaDevices.getUserMedia(constraints);

    constraints包括一下几种写法:

    • 请求音视频
    const constraints = {
        audio: true,
        video: true
    }
    
    • 请求特定的设备视频分辨率
    const constraints = {
        audio: true,
        video: {
             { 
                min: 1280 
            },
            height: { 
                min: 720 
            }
        }
    }
    
    • 使用前摄像头(默认)
    const constraints = {
        audio: true,
        video: {
            facingMode: "user"
        }
    }
    
    • 强制使用后置摄像头
    const constraints = {
        audio: true,
        video: {
            facingMode: {
                exact: "environment"
            }
        }
    }
    

    例如:

    const constraints = {
        audio: true,
        video: {
             1280,
            height: 720
        }
    };
    
    async function createMedia() {
        try {
            let stream = await navigator.mediaDevices.getUserMedia(constraints);
            var video = document.querySelector('video');
            video.srcObject = stream;
            video.onloadedmetadata = function (e) {
                video.play();
            };
        } catch (error) {
            console.log(`getUserMedia: ${error}`);
        }
    }
    
    createMedia();
    

    当然了这个stream还有一些方法可以使用,比如

    • addTrack 给流添加一个新轨道
    • getAudioTracks包含流中所有的音轨
    • getVideoTracks 于媒体流中包含的每个视频轨道
    • getTracks 此流的中的所有对象

    MediaRecorder

    这个就是录制流的一个方法。

    • start 开始录制
    • stop 结束录制
    • onstop 监听结束事件
    • ondataavailable 实时流数据

    语法var mediaRecorder = new MediaRecorder(stream[, options]);

    例如

    // stream就是上面获取的音视频流
    let options = {
        audioBitsPerSecond : 128000,
        videoBitsPerSecond : 2500000,
    }
    let mediaRecorder = new MediaRecorder(stream, options);
    
    // 实时的录制流数据
    mediaRecorder.ondataavailable = function (e) {  
        console.log(e.data);
    }
    
    // 监听停止录制事件并生成播放地址
    mediaRecorder.onstop = function () {
        let blob = new Blob(chunks, {'type': mediaRecorder.mimeType});
        let url = window.URL.createObjectURL(blob);
        console.log(url);
    }
    

    实战演练

    • 页面结构部分
    <audio controls src=""></audio>
    <video controls src="" style=" 100%;"></video>
    <button id="start">开始音频</button>
    <button id="stop">结束音频</button>
    <button id="play">播放音频</button>
    <button id="startVideo">开始视频</button>
    <button id="stopVideo">结束视频</button>
    <button id="playVideo">播放视频</button>
    
    • js部分

    获取元素添加事件

    // 获取按钮
    let audioStart = document.querySelector('#start');
    let audioStop = document.querySelector('#stop');
    let audioPlay = document.querySelector('#play');
    let startVideo = document.querySelector('#startVideo');
    let stopVideo = document.querySelector('#stopVideo');
    let playVideo = document.querySelector('#playVideo');
    
    // 音频操作
    audioStart.onclick = function () {  
        start('audio');
    }
    
    audioStop.onclick = function () {  
        stop('audio');
    }
    
    audioPlay.onclick = function () {  
        document.querySelector('audio').play();
    }
    
    // 视频操作
    startVideo.onclick = function () {  
        start('video');
    }
    
    stopVideo.onclick = function () {  
        stop('video');
    }
    
    playVideo.onclick = function () {  
        document.querySelector('video').play();
    }
    

    开始录制

    // 开始录制
    function start (type) {
        let option = type == 'audio' ? {
            audio: true
        } : {
            video: true,
        }
        createMedia(type, option);
    }
    

    停止录制

    // 停止录制
    function stop (type) {
        mediaRecorder.stop();
    }
    
    function stopSet (type) {  
        if (type == 'audio') {
            stream.getAudioTracks()[0].stop();
            stream = null;
        } else {
            stream.getVideoTracks()[0].stop();
        }
        stream = null;
        mediaRecorder = null;
        chunks = [];
        meida = null;
    }
    

    通用方法

    // 全局参数
    let stream = null,mediaRecorder = null,chunks = [], media = null;
    async function createMedia (type, option) {  
        try {
            // 获取媒体流
            stream = await navigator.mediaDevices.getUserMedia(option);
            media = document.querySelector(type);
            if (type === 'video') {
                media.srcObject = stream;
            }
            console.log(type, stream);
    
            // 录制流
            let options = {
                audioBitsPerSecond : 128000,
                videoBitsPerSecond : 2500000,
            }
            mediaRecorder = new MediaRecorder(stream, options);
            console.log(type, mediaRecorder);
    
            mediaRecorder.ondataavailable = function (e) {  
                chunks.push(e.data);
            }
    
            mediaRecorder.start();
    
            // 停止录制
            mediaRecorder.onstop = function () {
                let blob = new Blob(chunks, {'type': mediaRecorder.mimeType});
                let url = window.URL.createObjectURL(blob);
                if (type === 'video') {
                    media.srcObject = null;
                }
                media.src = url;
                stopSet(type);
            }
    
        } catch (error) {
            console.log('getUserMedia: ', error);
        }
    }
    

    看下效果

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    想要体验的可以打开这个音视频录制,手机上使用更佳。

    好了,今天的教程就介绍到这里,拜拜!

  • 相关阅读:
    【面积并】 Atlantis
    【动态前k大 贪心】 Gone Fishing
    【复杂枚举】 library
    【双端队列bfs 网格图建图】拯救大兵瑞恩
    【奇偶传递关系 边带权】 奇偶游戏
    【权值并查集】 supermarket
    CF w4d3 A. Pythagorean Theorem II
    CF w4d2 C. Purification
    CF w4d2 B. Road Construction
    CF w4d2 A. Cakeminator
  • 原文地址:https://www.cnblogs.com/guanqiweb/p/15172815.html
Copyright © 2011-2022 走看看