从0打造音视频直播系统
李超
前新东方音视频直播技术专家,前沪江音视频架构师
立即订阅
2827 人已学习
课程目录
已完结 40 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 5G的到来将会为音视频插上飞翔的翅膀
免费
WebRTC 1对1通话 (23讲)
01 | 原来通过浏览器访问摄像头这么容易
02 | 如何通过WebRTC进行音视频设备检测呢?
03 | 如何使用浏览器给自己拍照呢?
04 | 可以把采集到的音视频数据录制下来吗?
05 | 原来浏览器还能抓取桌面?
06 | WebRTC中的RTP及RTCP详解
07 | 你竟然不知道SDP?它可是WebRTC的驱动核心!
08 | 有话好商量,论媒体协商
09 | 让我们揭开WebRTC建立连接的神秘面纱
10 | WebRTC NAT穿越原理
11 | 如何通过Node.js实现一套最简单的信令系统?
12 | RTCPeerConnection:音视频实时通讯的核心
13 | 在WebRTC中如何控制传输速率呢?
14 | 如何打开/关闭音视频?
15 | WebRTC中的数据统计原来这么强大(上)
16 | WebRTC中的数据统计原来这么强大(下)
17 | 如何使用Canvas绘制统计图表(上)?
18 | 如何使用Canvas绘制统计图表(下)?
19 | WebRTC能不能进行文本聊天呢?
20 | 原来WebRTC还可以实时传输文件?
21 | 如何保证数据传输的安全(上)?
22 | 如何保证数据传输的安全(下)?
23 | 实战演练:通过WebRTC实现一个1对1音视频实时直播系统
WebRTC多人音视频实时通话 (7讲)
24 | 多人音视频实时通讯是怎样的架构?
25 | 那些常见的流媒体服务器,你该选择谁?
26 | 为什么编译Medooze Server这么难?
27 | 让我们一起探索Medooze的具体实现吧(上)
28 | 让我们一起探索Medooze的具体实现吧(下)
29 | 如何使用Medooze 实现多方视频会议?
30 | 实战演练:通过WebRTC实现多人音视频实时互动直播系统
支持上万人同时在线的直播系统 (8讲)
31 | 一对多直播系统RTMP/HLS,你该选哪个?
32 | HLS:实现一对多直播系统的必备协议
33 | FLV:适合录制的多媒体格式
34 | 如何使用Nginx搭建最简单的直播服务器?
35 | 如何构建云端一对多直播系统?
36 | 如何使用 flv.js 播放 FLV 多媒体文件呢?
37 | 如何使用 video.js 播放多媒体文件?
38 | 实战推演:带你实现一个支持万人同时在线的直播系统
结束语 (1讲)
结束语 | 路漫漫其修远兮,吾将上下而求索
从0打造音视频直播系统
登录|注册

03 | 如何使用浏览器给自己拍照呢?

李超 2019-07-20
在之前的文章中,我向你介绍了如何在浏览器中利用 WebRTC 采集音视频数据。那么,是否可以通过相同的技术进行拍照呢?没错,这是完全可行的。
现代的浏览器功能越来越强大,你不光可以通过它进行拍照,而且还可以对拍下来的照片进行各种滤镜处理。
为了实现上述功能,你需要了解并掌握以下三个知识点:
如何从采集到的视频中获取到图片?
如何将处理后的图片保存成文件?
如何对获取到的图片进行滤镜处理?
这三方面的知识点就是本文要交付的重点内容。下面我们先学习与之相关的基础知识和原理,然后再对这几个知识点逐一进行讲解,各个击破。

在 WebRTC 处理过程中的位置

在正式进入主题之前,咱们仍然按老规矩,看看本篇文章所介绍的内容在整个 WebRTC 处理过程中的位置。如下图所示:
WebRTC 1 对 1 音视频实时通话过程示意图
你可以看到,这张图与《01 | 原来通过浏览器访问摄像头这么容易》文章中的图一模一样。没错,咱们本篇文章所涉及的知识点仍然属于音视频数据采集的部分。

基础知识

在正式讲解如何进行拍照之前,你需要先了解非编码帧(解码帧)和编码帧这两个知识点,这会有利于你对后面拍照实现内容的理解。

1. 非编码帧

好多人小时候应该都学过,在几张空白的纸上画同一个物体,并让物体之间稍有一些变化,然后连续快速地翻动这几张纸,它就形成了一个小动画
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《从0打造音视频直播系统》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(21)

  • zer0fire
    老师,想问下滤镜效果要实际保存下来的话,是否需要转换成svg再转换成dataURI呢?我尝试了下似乎有点复杂,并且效果也不理想,会出现svg不能显示图片的情况。实际过程中保存滤镜的操作应该怎么做呢?

    作者回复: 可以参考 @恋着歌 同学的例子 https://codepen.io/anon/pen/rXOMYW, 实际上只需要对 canvas的 ctx 设置虑镜就可了!

    2019-07-22
    5
  • LongXiaJun
    现在每天都在等老师更新,凌晨快速看一遍,白天写笔记再看一遍,对于没有基础的同学可能会比较吃力,附上我的GitHub代码地址,供大家参考学习: https://github.com/KuKuXia/Real_Time_Communication_using_WebRTC

    作者回复: 赞!加油!

    2019-07-20
    3
  • xiao豪
    滤镜效果图片保存代码简单示例:
    。。。
    var filtersSelect = document.querySelector("select#filter");
    var selected = "";
    。。。
    document.querySelector("button#TakePhoto").onclick = function (){
        var ctx = picture.getContext('2d')
        console.log(ctx.filter)
        if(selected === "sepia"){
            ctx.filter = "sepia(1)";
        }else if(selected === "grayscale"){
            ctx.filter = "grayscale(1)";
        }else if(selected === "blur"){
            ctx.filter = "blur(3px)";
        }else if(selected === "invert"){
            ctx.filter = "invert(1)";
        }else{
            ctx.filter = "none";
        }
        ctx.drawImage(videoplay, 0, 0, picture.width, picture.height);
    }
    。。。
    filtersSelect.onchange = function (){
        selected = filtersSelect.value;
    }

    作者回复: 非常棒!

    2019-07-21
    1
    2
  • 流浪剑客
    老师,代码没跑起来。需要做如下修改。
    画布渲染图片需要改成触发动作,如下:
    document.querySelector("button#TakePhoto").onclick = function (){
        picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
    }
    下载图片画布名称需要改成picture,如下:
    downLoad(picture.toDataURL("image/jpeg"));

    作者回复: 下周一我会将相关的代码放到github上,耐心等待一下哈!

    2019-07-20
    2
  • Jim
    代码片段有点太零散,还好有点基础可以自己处理,对新手看起来估计就有点懵逼了。

    作者回复: 会有整体的代码供参考的!下周一就会出来哈

    2019-07-20
    2
  • halweg
    老师,滤镜都有了,
    要不要再加个瘦脸

    作者回复: 那个需要通过 WebGL 来处理,你可以自己研究一下哈!

    2019-07-26
    1
  • 王二宝
    ...

    function downLoad(url){
        var oA = document.createElement("a");
        oA.download = 'photo';// 设置下载的文件名,默认是'下载'
        oA.href = url;
        document.body.appendChild(oA);
        oA.click();
        oA.remove(); // 下载之后把创建的元素删除
    }

    ...
    document.querySelector("button#save").onclick = function (){
        downLoad(canvas.toDataURL("image/jpeg");)
    }
    ....
    老师,是不是应该去掉14行里面的那个分号。

    作者回复: 今天会处理掉,分号标错了!

    2019-07-26
    1
  • 王二宝
    ...

    function downLoad(url){
        var oA = document.createElement("a");
        oA.download = 'photo';// 设置下载的文件名,默认是'下载'
        oA.href = url;
        document.body.appendChild(oA);
        oA.click();
        oA.remove(); // 下载之后把创建的元素删除
    }

    ...
    document.querySelector("button#save").onclick = function (){
        downLoad(canvas.toDataURL("image/jpeg"););
    }
    ....
    这一段代码第14行多了一个分号。

    作者回复: 感谢! 感谢!

    2019-07-25
    1
  • 恋着歌
    要代码的同学 https://codepen.io/anon/pen/rXOMYW

    作者回复: 非常棒!

    2019-07-22
    1
  • 子飞鱼
    html2canvas. js 可以把dom和css渲染canvas

    作者回复: 测试了html2canvas. js的实际效果没?

    2019-07-22
    1
  • salmon
    老师可以整理代码作为demo传到github吗?前端新手有点整不明白。

    作者回复: 下周一就会有了,正在进行中......

    2019-07-20
    1
  • xiao豪
    调用drawImage方法时图片已经画好了,css只是对图片的渲染形式改变而已,所以下载的图片还是原图

    作者回复: 可以继续思考,如果能让下载的图片生效呢?

    2019-07-20
    1
  • LongXiaJun
    打卡~

    作者回复: 打卡〜

    2019-07-20
    1
  • qiezitx
    作业问题回答不上来,不懂浏览器原理。不过照老师的例子和同学的答案,拍照、保存、滤镜;作业保存滤镜图片都成功了。
    断舍离,非编码帧和编码帧,先记着最重要的信息。
    2019-12-11
  • 俊哥
    按照这个js代码,点拍照键canvas显示不出图片啊

    作者回复: 应该是没问题的,你是从git上下载的代码吗?

    2019-10-17
  • Eco
    最后的问题是用canvs重新再画一遍吗?

    作者回复: 不是,你可以看一下其它同学的留言,其实有问学已经给出答案来了!

    2019-08-15
    1
  • ZeroIce
    滤镜效果图片保存代码简单示例:
    ...
    snapshot.onclick = function () {
    let value = filtersSelect.value;
    var ctx = picture.getContext('2d');
    switch (value) {
    case "blur":
    ctx.filter = "blur(3px)";
    break;
    case "sepia":
    case "grayscale":
    case "invert":
    ctx.filter = value + "(1)";
    break;
    default:
    ctx.filter = "none";
    break;
    }
    // picture.className = filtersSelect.value;
    ctx.drawImage(videoplay, 0, 0, picture.width, picture.height);
    }
    ...

    作者回复: 赞!

    2019-08-02
  • 曙光
    老师,我 myCanvas.getContext('2d').filter = “sepia(1)”;修改了滤镜,alert()的结果也是“sepia(1)”,但下载的结果总是原图。但我把原图片保存到myImage, 重新myCanvas.getContext('2d').drawImage(myImage, 0, 0, myCanvas.width, myCanvas.height); 就可以下载滤镜图片。想问一下,为什么修改容器的filter,需要重新绘图才生效呢??

    作者回复: 可以看一下我下传的例子,对比学习一下!

    2019-07-29
  • 行知老王
    老师,您好,我是做了六七年java服务器端开发的老兵,大学里学习的c和c++早就还给老师了,您一直强调说以后后台是用c和c++,请问用java可以实现吗?还是说音视频这块的后台必须用c和c++?

    作者回复: 流媒体服务器要频繁接发包,对性能要求比较高,如果你要用Java的话,可以在底层用 JNI 调 C/C++程序

    2019-07-27
  • 终极数码杀手
    老师源码里的client.js里面line 14的stream是哪里来的,没看到哪里有定义呀

    作者回复: 回调的时候浏览器给传回来的!

    2019-07-24
收起评论
21
返回
顶部