安卓使用网络摄像头扫码

网络摄像头,是一种可以通过网络发送视频数据的视频设备,与基于模拟信号的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...

相关推荐
论迹复利7 分钟前
FreeRTOS 在 RISC-V 上是如何“点火“的 —— 从 main() 到第一个任务的完整链路
java·开发语言·risc-v
张宇Joaquin28 分钟前
鲲鹏统一并行加速库KUPL--众核并行能力介绍
java·开发语言·网络
宸津-代码粉碎机1 小时前
AI攻防战升级!基于Spring AI构建Java应用自动免疫安全体系
java·大数据·开发语言·人工智能·python·安全·spring
2601_963749102 小时前
越华环保集团数字化污水治理:端边云采集架构与平台对接实现
java·大数据·架构
鲨鱼辣钊2 小时前
FastAPI进阶_Day21_WebSocket实时通讯实战
websocket·网络协议·fastapi
xcLeigh2 小时前
Go入门:整数类型的溢出与安全边界
java·安全·golang
源码宝3 小时前
SpringBoot+Vue2 诊所门诊管理系统,完整前后端源码,可直接部署上线
java·源码·his系统·门诊系统·程序代码·诊所系统·门诊his
yychen_java3 小时前
九:Text-to-SQL 智能数据查询与 Human-in-the-Loop 人机协作
java·人工智能·架构
lhldsg4 小时前
智慧场馆解决方案小程序开发实战:从架构设计到部署指南
java·小程序·uni-app
Freak嵌入式4 小时前
Pico UART 数据收发实战:硬件配置、MicroPython 编程
java·开发语言·单片机·嵌入式硬件·生活