用JS get​User​Media调用摄像头展示上传

前言

    最近接手一个需求,页面上调用设备摄像头将拍摄的内容实时展示,用户可以随时截图上传,描述起来觉得挺简单,实际做了不少工作,特此记录。

get​User​Media使用环境

    目前获取摄像头流推荐的API是navigator.mediaDevices.getUserMedia,很多刚接触的小伙伴可能会发现自己的navigator找不到mediaDevices这个对象,如果你出现这种情况有两种方式可以解决,使用localhost或者https协议(推荐),我本人开发过程中使用Vue+webpack,对于https有很便捷的支持,只需要在webpack配置文件devServer选项中添加https: true 参考链接

注:如果你遇到程序出现req.handle.writev is not a function, 这种情况一般会发生在iphone请求https时候,我的解决方法是给node降级,没搜到什么好方法,参考自https://github.com/nodejs/node/issues/21665,都是泪...

给get​User​Media做个备胎

    并不是所有的用户浏览器都是支持get​User​Media,我们又不知道究竟各个浏览器哪个版本是支持的,为了兼容性我们给get​User​Media做个垫片,代码从MDN上copy而来。

// Older browsers might not implement mediaDevices at all, so we set an empty object first
if (navigator.mediaDevices === undefined) {
  navigator.mediaDevices = {};
}

// Some browsers partially implement mediaDevices. We can't just assign an object
// with getUserMedia as it would overwrite existing properties.
// Here, we will just add the getUserMedia property if it's missing.
if (navigator.mediaDevices.getUserMedia === undefined) {
  navigator.mediaDevices.getUserMedia = function(constraints) {

    // First get ahold of the legacy getUserMedia, if present
    var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

    // Some browsers just don't implement it - return a rejected promise with an error
    // to keep a consistent interface
    if (!getUserMedia) {
      return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
    }

    // Otherwise, wrap the call to the old navigator.getUserMedia with a Promise
    return new Promise(function(resolve, reject) {
      getUserMedia.call(navigator, constraints, resolve, reject);
    });
  }
}

调用get​User​Media

    所有的准备工作都已经做好了,那下一部分就是开始使用get​User​Media来获取视频流了,不出意外你就可以打开摄像头并且在video中播放实时画面了。

navigator.mediaDevices.getUserMedia({ audio: true, video: true })
.then(function(stream) {
  var video = document.querySelector('video');
  // Older browsers may not have srcObject
  if ("srcObject" in video) {
    video.srcObject = stream;
  } else {
    // Avoid using this in new browsers, as it is going away.
    video.src = window.URL.createObjectURL(stream);
  }
  video.onloadedmetadata = function(e) {
    video.play();
  };
})
.catch(function(err) {
  console.log(err.name + ": " + err.message);
});

iphone运行有问题

    如果上几步你都跟着做了,你应该发现在PC网页端可以完美运行,如果你尝试在移动端运行,运气好你先拿起了一部安卓手机,完美运行,你又拿起了一部iphone,what?为什么只有第一帧就卡住了(PS:iphone微信打开无法运行,我也没有解决,只能用Safari打开),找不到那篇说明文档了,大致说一下意思就是苹果对于网页端媒体开发进行了限制,会限制视频的自动播放,需要用户主动去触发授权。比如可以在onclick事件中调用,我看文档上写着还可以设置viedo无声(muted属性)也可以自动播放,我尝试并没有效果,结果就是加了一个按钮,让用户主动去调用video.play()。OK,那就好了吗?你会发现苹果会自己把video全屏,那有些时候这可能不是你想要的效果,解决方法,Safari在10版本前后有些差异,webkit-playsinline、playsinline作用相同,只不过为了更全面的兼容性。

<video muted webkit-playsinline='true' playsinline='true'></video>

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OAuth2是一种授权协议,用于保护API和应用程序。RestTemplate是Spring框架提供的一个用于发送HTTP请求的工具类。使用RestTemplate调用OAuth2授权的服务涉及到以下步骤: 1. 获取访问令牌(access token):在OAuth2授权流程中,客户端需要向授权服务器发送请求,获取访问令牌。这个过程需要传递客户端ID和密钥等信息。可以使用RestTemplate发送HTTP请求来实现这个过程。 2. 使用访问令牌访问受保护的资源:获取访问令牌之后,客户端可以使用这个令牌访问OAuth2保护的资源。在访问这些资源时,客户端需要在HTTP请求头中传递访问令牌。同样可以使用RestTemplate发送HTTP请求来实现这个过程。 下面是一个使用RestTemplate调用OAuth2授权的服务的示例: ``` // 创建RestTemplate实例 RestTemplate restTemplate = new RestTemplate(); // 发送获取访问令牌的请求 String url = "http://oauthserver.com/token"; MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("grant_type", "client_credentials"); params.add("client_id", "your_client_id"); params.add("client_secret", "your_client_secret"); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers); ResponseEntity<TokenResponse> response = restTemplate.postForEntity(url, request, TokenResponse.class); // 获取访问令牌 String accessToken = response.getBody().getAccessToken(); // 使用访问令牌访问受保护的资源 url = "http://protectedresource.com/api/v1/users"; headers = new HttpHeaders(); headers.setBearerAuth(accessToken); request = new HttpEntity<>(headers); response = restTemplate.exchange(url, HttpMethod.GET, request, UserListResponse.class); // 处理响应结果 List<User> userList = response.getBody().getUsers(); ``` 在这个示例中,我们首先创建了一个RestTemplate实例。然后,我们发送获取访问令牌的请求,使用postForEntity方法发送HTTP POST请求,传递授权服务器的URL、请求参数和请求头信息。在响应中,我们解析访问令牌,并将其存储在accessToken变量中。 接下来,我们使用RestTemplate访问受保护的资源。我们使用exchange方法发送HTTP GET请求,传递受保护资源的URL和请求头信息。在响应中,我们解析受保护资源的响应结果,并将其存储在userList变量中。 这是一个基本的示例,你可以根据实际需求进行修改和扩展。需要注意的是,这个示例中并没有处理访问令牌的过期和刷新等问题,你需要根据实际情况进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值