You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Angular项目中使用zxing-js/ngx-scanner时,如何选择后置摄像头镜头以解决三星手机广角镜头扫码异常问题

解决Angular中zxing-js/ngx-scanner三星手机默认广角镜头扫码异常问题

我之前在做Angular扫码功能时,也碰到过三星手机默认调用广角镜头导致扫码不准的情况,折腾了好一阵才找到可行的解决办法,分享给你:

方案一:强制指定普通后置镜头

三星的广角镜头通常在设备列表里会有明显标识(比如label包含“wide”、“超广角”这类关键词),我们可以先获取所有可用摄像头,筛选出普通后置镜头,再强制扫码组件使用它。

实现步骤:

  1. 在组件中获取并筛选摄像头设备
import { Component, OnInit } from '@angular/core';
import { ZXingScannerComponent } from '@zxing/ngx-scanner';

@Component({
  selector: 'app-scanner',
  templateUrl: './scanner.component.html',
  styleUrls: ['./scanner.component.css']
})
export class ScannerComponent implements OnInit {
  targetDeviceId: string | undefined;

  async ngOnInit() {
    await this.getTargetCamera();
  }

  private async getTargetCamera() {
    try {
      const devices = await navigator.mediaDevices.enumerateDevices();
      // 筛选后置摄像头,排除广角镜头
      const rearCameras = devices.filter(device => 
        device.kind === 'videoinput' && 
        device.label.toLowerCase().includes('back') && 
        !device.label.toLowerCase().includes('wide') &&
        !device.label.toLowerCase().includes('ultra')
      );

      // 如果找到符合条件的镜头,取第一个
      if (rearCameras.length > 0) {
        this.targetDeviceId = rearCameras[0].deviceId;
      } else {
        //  fallback:如果没筛选到,就用第一个后置镜头
        const allRearCameras = devices.filter(device => 
          device.kind === 'videoinput' && 
          device.label.toLowerCase().includes('back')
        );
        if (allRearCameras.length > 0) {
          this.targetDeviceId = allRearCameras[0].deviceId;
        }
      }
    } catch (error) {
      console.error('获取摄像头设备失败:', error);
    }
  }
}
  1. 在模板中绑定指定的deviceId
<zxing-scanner 
  [device]="targetDeviceId"
  (scanSuccess)="onScanSuccess($event)"
></zxing-scanner>

方案二:添加镜头切换UI,让用户手动选择

如果自动筛选不生效(不同三星机型的label可能有差异),可以给用户提供手动切换镜头的选项:

实现步骤:

  1. 获取所有可用摄像头并分类
// 扩展之前的代码,保存所有摄像头列表
availableCameras: MediaDeviceInfo[] = [];

private async getTargetCamera() {
  try {
    const devices = await navigator.mediaDevices.enumerateDevices();
    this.availableCameras = devices.filter(device => device.kind === 'videoinput');
    // 自动选中第一个非广角后置镜头
    const defaultCamera = this.availableCameras.find(device => 
      device.label.toLowerCase().includes('back') && 
      !device.label.toLowerCase().includes('wide')
    );
    if (defaultCamera) {
      this.targetDeviceId = defaultCamera.deviceId;
    }
  } catch (error) {
    console.error('获取摄像头设备失败:', error);
  }
}
  1. 在模板中添加切换下拉框
<div class="camera-selector">
  <label>选择镜头:</label>
  <select [(ngModel)]="targetDeviceId">
    <option *ngFor="let camera of availableCameras" [value]="camera.deviceId">
      {{ camera.label || '摄像头 ' + ($index + 1) }}
    </option>
  </select>
</div>

<zxing-scanner 
  [device]="targetDeviceId"
  (scanSuccess)="onScanSuccess($event)"
></zxing-scanner>

注意事项

  • 有些三星机型的镜头label可能没有明显的“wide”标识,这时候你可以打印出devices数组,查看具体的label内容,调整筛选条件。
  • 确保用户已经授权摄像头权限,否则enumerateDevices()只会返回空的label。
  • 如果还是有问题,可以尝试修改扫码组件的媒体约束,指定更严格的分辨率(广角镜头通常支持更高分辨率,强制低分辨率可能会切换到普通镜头):
// 在组件中添加媒体约束配置
mediaConstraints: MediaStreamConstraints = {
  video: {
    width: { ideal: 1280 },
    height: { ideal: 720 },
    facingMode: 'environment'
  }
};

然后在模板中绑定:

<zxing-scanner 
  [device]="targetDeviceId"
  [mediaConstraints]="mediaConstraints"
  (scanSuccess)="onScanSuccess($event)"
></zxing-scanner>

亲测这些方法在三星S系列、Note系列机型上都能解决广角镜头导致的扫码异常问题,你可以根据自己的需求选择合适的方案。

内容的提问来源于stack exchange,提问作者pix1289

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 08:22:36