通过浏览器获取相机访问权限

155

我们正在为移动设备创建一个HTML5网站,需要通过Web浏览器获取相机访问权限,而不是作为本地应用程序。我们在iOS上遇到了问题,无法实现此功能。有人知道这个问题的解决方案吗?

6个回答

129

你可以尝试这个:

<input type="file" capture="camera" accept="image/*" id="cameraInput" name="cameraInput">

但必须是 iOS 6+ 才能工作。这将为您提供一个不错的对话框,让您选择是拍照还是从相册上传一张图片,如下图所示:

屏幕截图

此处可找到一个示例: 在不使用 PhoneGap 的情况下捕获相机 / 图片数据


6
在安卓上这也太棒了! - Matt
1
漂亮的上传服务器演示。有人知道如何修改它以将图片保存到设备上的本地相册吗? - K.Niemczyk
2
唯一的问题是,在 iPhone 上(iOS 7.0.4),至少目前它会创建一个名为“image.jpg”的临时图像。因此,如果您在同一表单中上传几个图像,则由于名称相同它们会彼此覆盖,除非您对它们进行重命名,要小心! - aleation
@K.Niemczyk:你解决了吗?如果有的话,我对解决方案很感兴趣。我找到了这个:http://dev.w3.org/2009/dap/camera/(请参见本地存储的示例6-7)。 - lamarant
1
太棒了。这里有一个fiddle,供任何想在他们的设备上测试此代码的人使用。 - Simon East
显示剩余6条评论

34

截至2015年,它现在只是有效地工作

<input type="file">

这将要求用户上传任何文件。在iOS 8.x中,这可以是相机视频、相机照片或来自照片库的照片/视频。

iOS/iPhone照片/视频/文件上传

<input type="file" accept="image/*">

这与上述相同,但仅限于从相机或库上传照片,不允许上传视频。


1
有没有办法限制用户从照片库中选择文件?我只想接受新拍摄的图像。 - Daryl
@Daryl 不支持iOS。Android支持capture属性,可以实现这一功能。请参阅HTML媒体捕获的正确语法 - octavn
如果用户没有点击它,我应该在一段时间后关闭这个“拍照或视频”和“照片库”弹出窗口吗? - Pritish
视频功能好像不再存在了? - MartianMartian

26

10

我认为这个可以工作。 录制视频或音频;

<input type="file" accept="video/*;capture=camcorder">
<input type="file" accept="audio/*;capture=microphone">

或者(新方法)

<device type="media" onchange="update(this.data)"></device>
<video autoplay></video>
<script>
  function update(stream) {
    document.querySelector('video').src = stream.url;
  }
</script>
如果不是这样,可能会在ios6上工作,详细信息可以在获取用户媒体中找到。

5
更新于2020年11月: Google Developer链接已失效。原始文章包含更多解释,可在web.archive.org上找到。


虽然这个问题已经有几年了,但在此期间出现了一些额外的可能性,例如直接访问相机,显示预览和捕获快照(例如用于QR码扫描)。

Google Developers提供了一个深入的解释,介绍了所有获取图像/相机数据并将其应用于Web应用程序的方式,从“无处不在”(甚至在桌面浏览器中也可以使用)到“仅在现代的、最新的移动设备上使用相机”。还提供了许多有用的技巧。

解释的方法如下:

  • 请求URL:最简单但最不令人满意的方法。

  • 文件输入(大多数其他帖子都有涉及):然后可以将数据附加到<input>或通过在输入元素上侦听onchange事件并读取事件目标的files属性来使用JavaScript进行操作。

<input type="file" accept="image/*" id="file-input">
<script>
  const fileInput = document.getElementById('file-input');

  fileInput.addEventListener('change', (e) => doSomethingWithFiles(e.target.files));
</script>

files属性是一个FileList对象。

  • 拖放文件(适用于桌面浏览器):
<div id="target">You can drag an image file here</div>
<script>
  const target = document.getElementById('target');

  target.addEventListener('drop', (e) => {
    e.stopPropagation();
    e.preventDefault();

    doSomethingWithFiles(e.dataTransfer.files);
  });

  target.addEventListener('dragover', (e) => {
    e.stopPropagation();
    e.preventDefault();

    e.dataTransfer.dropEffect = 'copy';
  });
</script>

您可以从drop事件的dataTransfer.files属性中获取一个FileList对象。

  • 从剪贴板粘贴
<textarea id="target">Paste an image here</textarea>
<script>
  const target = document.getElementById('target');

  target.addEventListener('paste', (e) => {
    e.preventDefault();
    doSomethingWithFiles(e.clipboardData.files);
  });
</script>

e.clipboardData.files是一个FileList对象。

  • 交互式地访问相机(如果应用程序需要即时反馈它“看到”的内容,例如QR码,则必要):使用const supported = 'mediaDevices' in navigator;检测相机支持,并提示用户授权。然后显示实时预览并将快照复制到画布中。
<video id="player" controls autoplay></video>
<button id="capture">Capture</button>
<canvas id="canvas" width=320 height=240></canvas>
<script>
  const player = document.getElementById('player');
  const canvas = document.getElementById('canvas');
  const context = canvas.getContext('2d');
  const captureButton = document.getElementById('capture');

  const constraints = {
    video: true,
  };

  captureButton.addEventListener('click', () => {
    // Draw the video frame to the canvas.
    context.drawImage(player, 0, 0, canvas.width, canvas.height);
  });

  // Attach the video stream to the video element and autoplay.
  navigator.mediaDevices.getUserMedia(constraints)
    .then((stream) => {
      player.srcObject = stream;
    });
</script>

不要忘记使用以下命令停止视频流:

player.srcObject.getVideoTracks().forEach(track => track.stop());
2020年11月更新: Google Developer的链接目前已失效。原始文章提供了更多解释,可在web.archive.org找到。


这就是为什么链接答案也应该在回答中包含具体信息,因为链接可能会失效。 - mikeb
我在网络档案中找到了原始文章并添加了示例。希望能取消踩票。 - Christoph

4

Picup 应用程序是一种从 HTML5 页面拍照并将其上传到您的服务器的方式。它需要服务器上的一些额外编程,但除了 PhoneGap,我没有找到其他方法。


5
在iOS8中,您不再需要使用Picup。HTML5支持<input type="file" accept="image/*" id="capture" capture="camera">。在Safari和Chrome中已验证。 - rakensi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接