安卓使用网络摄像头扫码

网络摄像头,是一种可以通过网络发送视频数据的视频设备,与基于模拟信号的CCTV摄像头不同,我们可以在我们的应用中接受它的数字信号。

网络摄像头广泛用于监控。它们还可以用于库存管理,也可以用作Android平板电脑和自动售货机等设备的额外摄像头。

在本文中,我们将使用创建一个使用网络摄像头进行扫码的Android应用。使用ExoPlayer通过RTSP播放网络摄像头的视频流,Dynamsoft Barcode Reader用于识别条码。

新建项目

使用Android Studio创建一个空的activity的应用项目。

添加依赖项

  1. 在应用的build.gradle中添加ExoPlayer。

    groovy 复制代码
    implementation "androidx.media3:media3-exoplayer:1.4.1"
    implementation "androidx.media3:media3-exoplayer-dash:1.4.1"
    implementation "androidx.media3:media3-ui:1.4.1"
    implementation "androidx.media3:media3-exoplayer-rtsp:1.4.1"
  2. 添加Dynamsoft Barcode Reader。

    1. 打开settings.gradle添加Dynamsoft的maven仓库。

      groovy 复制代码
      dependencyResolutionManagement {
          repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
          repositories {
              google()
              mavenCentral()
              maven {
                  url "https://download2.dynamsoft.com/maven/aar"
              }
          }
      }
    2. 在应用的build.gradle中声明依赖。

      groovy 复制代码
      implementation 'com.dynamsoft:dynamsoftbarcodereaderbundle:10.4.2000'

添加权限

打开AndroidManifest.xml以添加Internet权限。

xml 复制代码
<uses-permission android:name="android.permission.INTERNET"></uses-permission>

使用ExoPlayer播放网络摄像头的RTSP流

  1. 打开activity_main.xml,添加PlayerView。

    xml 复制代码
    <androidx.media3.ui.PlayerView
        android:id="@+id/playerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:surface_type="surface_view" >
    </androidx.media3.ui.PlayerView>

    MainActivity.java中,获取该视图。

    java 复制代码
    private PlayerView playerView;
    playerView = findViewById(R.id.playerView);
  2. 创建ExoPlayer的实例并将其设置为PlayerView的播放器。

    java 复制代码
    ExoPlayer player = new ExoPlayer.Builder(getApplicationContext()).build();
    playerView.setPlayer(player);
  3. 将RTSP流设置为播放器的媒体源。可以使用mediamtx启动一个本地RTSP服务器进行测试。

    java 复制代码
    protected Uri uri = Uri.parse("rtsp://192.168.8.65:8554/mystream");
    MediaSource mediaSource =
                 new RtspMediaSource.Factory()
                    .createMediaSource(MediaItem.fromUri(uri));
    player.setMediaSource(mediaSource);
  4. 准备播放器,并在准备就绪后进行播放。

    java 复制代码
    player.setPlayWhenReady(true);
    player.prepare();

从网络摄像头读取条码

  1. 初始化Dynamsoft Barcode Reader的许可证。可以在此处申请许可证

    java 复制代码
    LicenseManager.initLicense("DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==", this, (isSuccess, error) -> {
        if (!isSuccess) {
            error.printStackTrace();
        }
    });
  2. 创建capture vision router实例以调用Dynamsoft Barcode Reader来解码。

    java 复制代码
    private CaptureVisionRouter mRouter;
    mRouter = new CaptureVisionRouter(this);
  3. 启动一个计时器以捕获网络摄像头的视频帧并从中读取条形码。在TextView中显示结果。

    java 复制代码
    private boolean decoding = false;
    private boolean isVideoPlaying = false;
    private Timer timer = null;
    private void startDecoding(){
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                takePhotoAndDecode();
            }
        };
        timer = new Timer();
        timer.schedule(task, 1000,100);
    }
    
     @OptIn(markerClass = UnstableApi.class)
     @SuppressLint("NewApi")
     private void takePhotoAndDecode() {
        if (decoding == false && isVideoPlaying) {
            decoding = true;
            SurfaceView surfaceView = (SurfaceView) playerView.getVideoSurfaceView();
            // Create a bitmap the size of the scene view.
            final Bitmap bitmap = Bitmap.createBitmap(surfaceView.getWidth(), surfaceView.getHeight(),
                    Bitmap.Config.ARGB_8888);
            // Create a handler thread to offload the processing of the image.
            final HandlerThread handlerThread = new HandlerThread("PixelCopier");
            handlerThread.start();
            // Make the request to copy.
            PixelCopy.request(surfaceView, bitmap, (copyResult) -> {
                if (copyResult == PixelCopy.SUCCESS) {
                    CapturedResult result =  mRouter.capture(bitmap, EnumPresetTemplate.PT_READ_BARCODES);
                    DecodedBarcodesResult decodedBarcodesResult = result.getDecodedBarcodesResult();
                    if (decodedBarcodesResult != null) {
                        BarcodeResultItem[] items = decodedBarcodesResult.getItems();
                        StringBuilder sb = new StringBuilder();
                        for (BarcodeResultItem item:items) {
                            sb.append(item.getFormatString());
                            sb.append(": ");
                            sb.append(item.getText());
                            sb.append("\n");
                        }
                        runOnUiThread(new Runnable() {
                            public void run() {
                                textView.setText(sb.toString());
                            }
                        });
                    }
                }
                decoding = false;
                handlerThread.quitSafely();
            }, new Handler(handlerThread.getLooper()));
        }
    }
  4. 为播放器添加监听器来检查视频是否正在播放。

    java 复制代码
    player.addListener(
        new Player.Listener() {
            @Override
            public void onIsPlayingChanged(boolean isPlaying) {
                isVideoPlaying = isPlaying;
            }
        });

好了,我们已经完成了这个demo。

源代码

查看demo的源代码并尝试使用:

github.com/tony-xlh/IP...

相关推荐
卓怡学长几秒前
m326数据结构课程网络学习平台的设计与实现+vue
java·spring·tomcat·maven·intellij-idea·mybatis
JJay.2 分钟前
Android 17 大屏适配变化解
android
han_hanker32 分钟前
@Validated @Valid 用法
java·spring boot
小CC吃豆子33 分钟前
详细介绍一下静态分析工具 SonarQube
java
DevOpenClub36 分钟前
全国三甲医院主体信息 API 接口
java·大数据·数据库
言慢行善44 分钟前
SpringBoot中的注解介绍
java·spring boot·后端
一勺菠萝丶1 小时前
管理后台使用手册在线预览与首次登录引导弹窗实现
java·前端·数据库
BullSmall1 小时前
Prometheus 如何配置监控 SSL 证书即将过期
网络协议·ssl·prometheus
TE-茶叶蛋1 小时前
结合登录页-PHP基础知识点解析
android·开发语言·php
无巧不成书02181 小时前
Java包(package)全解:从定义、使用到避坑,新手零基础入门到实战
java·开发语言·package·java包