在 Android 上录制视频时拍照

2023-11-26

我编写了如下所示的 Android 服务,用于在后台录制前置摄像头。这非常有效。但现在我想在录制时每 5 秒拍一张照片。这有可能吗?当我尝试打开第二个摄像头(在另一个服务中)时,出现错误。

public class RecorderService extends Service implements SurfaceHolder.Callback {

    private WindowManager windowManager;
    private SurfaceView surfaceView;
    private Camera camera = null;
    private MediaRecorder mediaRecorder = null;

    @Override
    public void onCreate() {
        // Create new SurfaceView, set its size to 1x1, move it to the top left corner and set this service as a callback
        windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        surfaceView = new SurfaceView(this);
        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
                1, 1,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT
        );
        layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
        windowManager.addView(surfaceView, layoutParams);
        surfaceView.getHolder().addCallback(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Intent notificationIntent = new Intent(this, MainActivity.class);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                notificationIntent, 0);

        Notification notification = new NotificationCompat.Builder(this)
                //.setSmallIcon(R.mipmap.app_icon)
                .setContentTitle("Background Video Recorder")
                .setContentText("")
                .setContentIntent(pendingIntent).build();

        startForeground(MainActivity.NOTIFICATION_ID_RECORDER_SERVICE, notification);
        return Service.START_NOT_STICKY;
    }

    // Method called right after Surface created (initializing and starting MediaRecorder)
    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        camera = Camera.open(1);
        mediaRecorder = new MediaRecorder();
        camera.unlock();

        mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
        mediaRecorder.setCamera(camera);
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_720P));

        FileUtil.createDir("/storage/emulated/0/Study/Camera");
        mediaRecorder.setOutputFile("/storage/emulated/0/Study/Camera/" + Long.toString(System.currentTimeMillis()) + ".mp4");

        try { mediaRecorder.prepare(); } catch (Exception e) {}
        mediaRecorder.start();

        try {
            camera.setPreviewDisplay(surfaceHolder);
        } catch (IOException e) {
            e.printStackTrace();
        }

        Runnable runnable = new PictureThread(camera);
        Thread thread = new Thread(runnable);
        thread.start();
    }

    // Stop recording and remove SurfaceView
    @Override
    public void onDestroy() {
        mediaRecorder.stop();
        mediaRecorder.reset();
        mediaRecorder.release();

        camera.lock();
        camera.release();

        windowManager.removeView(surfaceView);
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {}

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {}

    @Override
    public IBinder onBind(Intent intent) { return null; }
}

Edit: 我已经写了一个帖子了PictureThread。该线程开始于RecorderService并尝试在录制视频时拍照。

public class PictureThread implements Runnable {
    private final static String TAG = PictureThread.class.getSimpleName();

    private Camera camera;

    PictureThread(Camera camera) {
        this.camera = camera;
    }

    @Override
    public void run() {
        camera.startPreview();
        camera.takePicture(shutterCallback, rawCallback, jpegCallback);
    }

    Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() {
        public void onShutter() {
        }
    };

    Camera.PictureCallback rawCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
        }
    };

    Camera.PictureCallback jpegCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            Log.i(TAG, "onPictureTaken - jpeg");
        }
    };
}

很遗憾jpegCallback永远不会被调用(即日志消息永远不会被打印)。当我打开平板电脑的相机应用程序时,我可以在录制视频的同时拍照,所以这应该是可能的。

我还尝试了 Alex Cohn 建议的 Camera2 API 示例(https://github.com/mobapptuts/android_camera2_api_video_app)。录制视频和拍照都可以,但是当我尝试在录制时拍照时,不会创建图片(但也没有错误)。尽管如此,我发现这个示例应用程序运行得不太可靠(也许还有另一个示例应用程序)。

Edit 2: The shutterCallback and rawCallback of takePicture被调用,但数据rawCallback一片空白。这jpegCallback永远不会被调用..知道为什么以及如何解决这个问题吗?我还尝试在线程中等待一段时间,以便为回调提供被调用的时间,并且我尝试在我的主要活动中使回调静态(以便它不会被垃圾收集)。什么都没起作用。


Edit:

澄清一下:

旧的相机 API 支持在录制视频时调用 takePicture(),如果Camera.Parameters.isVideoSnapshotSupported设备上的报告是否正确是有问题的。

只需保留您传递到 MediaRecorder 的同一个相机实例,然后对其调用 Camera.takePicture() 即可。

Camera2 还通过同时创建具有预览、录制和 JPEG 输出的会话来更灵活地支持此功能。

原答案:

如果您的意思是使用后置摄像头拍照,同时使用前置摄像头录制 - 这取决于设备。有些设备有足够的硬件资源来同时运行多个摄像头,但大多数设备不会(它们在两个摄像头之间共享处理硬件)。

判断是否可以同时使用多个摄像头的唯一方法是在已经打开第二个摄像头的情况下尝试打开第二个摄像头。如果有效,你就可以走了;如果不是,则该设备不支持同时使用多个摄像头。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Android 上录制视频时拍照 的相关文章

  • APK META-INF/library_release.kotlin_module 中复制的重复文件

    我最近通过 JitPack 添加了两个 Android 库 但出现以下错误 Duplicate files copied in APK META INF library release kotlin module 我已经清除了缓存 并尝试使
  • 如何检测android中的颠倒方向?

    在我的 Android 应用程序中 我有全景图像 并且我使用 TYPE ORIENTATION 传感器根据手机运动旋转该图像 它对于横向和纵向都工作良好 这是旋转逻辑的代码 Override public void onSensorChan
  • 为网络和/或持久存储序列化 Android Bundle?

    我需要序列化一个全面的应用程序 游戏 状态 以便通过网络传输或保存到磁盘并在以后检索 当然 捆绑包用于在多个用例中保存 恢复状态 因此使用它们将是理想的选择 但是 由于某种原因 Bundle 不可序列化 寻找解决方案只发现了将 Bundle
  • 如何在 android-studio 0.3.6 中运行 Gradle 1.9?

    我只是花了一些时间尝试将现有的 android studio 项目从 gradle 1 8 迁移到 gradle 1 9 Final 昨天发布 但失败了19th Nov 我在这里阅读了大多数其他与 gradle 相关的帖子 但没有一个对我有
  • PhoneGap 是应用程序开发的好选择吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 用于代码生成的 ANTLR 工具版本 4.7.1 与当前运行时版本 4.5.3 不匹配

    我正在开发一个 Android 应用程序 当前使用 DSL 和一些库 突然构建给了我这个错误 任务 app kaptDebugKotlin 失败 用于代码生成的 ANTLR 工具版本 4 7 1 与当前运行时版本 4 5 3 不匹配 用于解
  • 将 ArrayList 保存在捆绑包 savingInstanceState 中

    ArrayList 是在类级别定义的 这些是我保存的实例方法 Override protected void onSaveInstanceState Bundle outState super onSaveInstanceState out
  • 如何在Firebase Android应用程序中分离两个不同的用户?

    我有一个应用程序 有两种不同类型的用户 一种是教师 第二种是普通用户 如果普通会员登录 他会去normal memberActivity如果他是教师会员 他会去Teacher memberActivity 我如何在登录活动中执行此操作 我的
  • Android接收通知打开和取消事件

    我从 webService 接收数据以生成自定义通知 我想追踪Intent要知道open 点击 或cancel 滑动 通知上的事件 以报告服务器进行分析 有没有听众onIntentStart or onIntentCanceled 也许是通
  • NoClassDefFoundError:com.google.firebase.FirebaseOptions

    我继续得到NoClassDefFoundError在我正在使用的其他测试设备 4 4 2 上 但在我的测试设备 Android 5 1 上运行良好 我尝试了用谷歌搜索的解决方案 但似乎没有任何效果 我正在使用 Firebase 实时数据库
  • UnsupportedOperationException:特权进程中不允许使用 WebView

    我在用android sharedUserId android uid system 在我的清单中获得一些不可避免的权利 从 HDMI 输入读取安卓盒子 http eweat manufacturer globalsources com s
  • 在Android的activity中调用onResume

    在活动的过程中通过调用 this OnResume 强制 onResume 事件可以吗 或者我应该实现另一个由 OnResume 和第一个成员调用的过程 实现在您的重写中调用的另一个过程onResume 后者不打算由您调用 它是一种方便的方
  • EditText 的高度不会扩展到其父级的高度

    我在滚动视图中放置了编辑文本 高度 match parent并期望它的高度等于滚动视图 但事实并非如此 它的高度就像wrap content这意味着如果 EditText 中没有文本 我必须将光标指向要弹出的软键盘的第一 行 我想要的是我可
  • MPAndroidChart:组合图表

    我在用MPAndroidChart 库 https github com PhilJay MPAndroidChart 我想用CombinedChart创建这样的图表 那可能吗 我尝试了一下 但似乎不起作用 因为 这些条目没有按我的预期工作
  • Android apk 调试模式工作正常,但发布模式给出太多警告

    我正在尝试从 eclipse 获取签名的 APK 我有一个可调试的 apk 版本 运行良好 现在发布时 当我尝试使用 Eclipse ADT 进行编译和签名时 我收到很多警告 其中大部分是can t find superclass or i
  • onTouch 给出奇怪的触摸点 Android

    我正在做的事情非常简单 我以前做过 但现在它没有按我的预期运行 无论如何 让我简要解释一下我正在尝试做什么以及我得到了什么 设想 我有一个RelativeLayout其中一个ImageView已放置 现在我设置touchlistener像这
  • 在 Android SDK 中通过单击按钮更改背景颜色不起作用

    我有一个简单的程序 可以在单击按钮后更改背景颜色 但它不起作用 public class ChangeBackgroundActivity extends Activity Called when the activity is first
  • Java中如何限制文件大小

    我正在我的应用程序中创建一个文件 并继续向该文件中写入一些内容 但是当我的文件达到一定大小 比如说 100 行 后 我想删除第一行并将新行写入底部 要求是我的文件应该受到限制 但它应该保留我写入文件的最新内容 请告诉我在Java中是否可行
  • 在android中的日期选择器对话框中显示当前日期

    我多次尝试在日期选择器对话框中显示当前日期 但失败了 它显示 1 1 1990 我已经遵循了堆栈溢出的一些答案 但不幸的是这些对我不起作用 谁能解释一下在日期选择器对话框中显示当前日期的代码 谢谢 It may help you publi
  • TYPE_ACCELEROMETER 和 TYPE_LINEAR_ACCELERATION 传感器有什么区别?

    I think TYPE ACCELEROMETER显示设备加速 但是 我不明白什么时候应该使用TYPE LINEAR ACCELERATION 我需要计算移动设备的速度 哪种传感器适合此应用 另外 我读到TYPE LINEAR ACCEL

随机推荐

  • 运行 MySQL CREATE TABLE 语句时出现语法错误[重复]

    这个问题在这里已经有答案了 CREATE TABLE users user id INT 8 NOT NULL AUTO INCREMENT user name VARCHAR 30 NOT NULL user pass VARCHAR 2
  • PL/SQL 开发人员导入转储

    我有一个转储文件 其中包含两个表 现在我需要导入这个转储文件 我被指示预先创建两个表空间 现在如何将此转储文件导入到这些表空间中 我正在使用 PL SQL 开发人员 您无法从 PL SQL Developer 导入转储文件 相反 您必须从命
  • 文件访问中文本模式和二进制模式有什么区别吗?

    如果我以文本模式而不是二进制模式打开文件有什么区别吗 因为我读到UNIX和Linux不区分文本和二进制文件 在 Linux 上没有区别 至少在 Ext4 等本机文件系统上 以及大多数其他文件系统上 以及通常的 GNU libc Perhap
  • 可迭代解包的默认值

    我经常因 Python 的可迭代解包缺乏灵活性而感到沮丧 举个例子 a b range 2 工作正常 a包含0 and b包含1 正如预期的那样 现在让我们试试这个 a b range 1 现在 我们得到一个ValueError Value
  • 用户定义文字的每个“正常”使用都是未定义行为吗?

    用户定义的文字must以下划线开头 这是一条或多或少众所周知的规则 您可以在每个谈论用户文字的外行语言网站上找到它 这也是我 可能还有其他人 从那时起就以 胡说八道 为由公然忽视的规则 当然 现在看来这是完全不正确的 从最严格的意义上来说
  • Flow 不更新可组合项

    我遇到了以下问题 这是注册屏幕 上面有几个输入字段 当用户输入内容时 该值会传递到 ViewModel 设置为屏幕状态并通过 StateFlow 传回屏幕 从可组合项中 我正在观察这个 StateFlow 问题是 Composable 在向
  • 没有有用且可靠的方法来检测 C/C++ 中的整数溢出?

    不 这不是重复的如何检测整数溢出 问题是一样的 但是问题不同 gcc 编译器可以优化溢出检查 使用 O2 例如 int a b b abs a will overflow if a 0x80000000 if b lt 0 printf o
  • Estimator 的 model_fn 包含 params 参数,但 params 不会传递给 Estimator

    我正在尝试在本地运行对象检测 API 我相信我已按照中所述设置了所有内容TensorFlow 对象检测 API然而 当我尝试运行 model main py 时 此警告显示并且模型无法训练 我无法真正判断模型是否正在训练 因为该过程没有终止
  • 有 com.l2fprod.common.propertysheet.PropertySheetPanel 来显示组合类

    为了拥有 Netbeans 喜欢的属性检查器窗口 我使用以下类来帮助我实现这一目标 com l2fprod common propertysheet PropertySheetPanel 到目前为止 它对于具有简单属性 例如 String
  • 在 NextJS 项目中使用 Tailwind 和 MUI 时出现意外行为(白色按钮错误)

    我目前正在使用 NextJS TailwindCSS 和 MUI React UI 库构建一个项目 每当我尝试向我的项目添加 MUI 按钮时 它工作正常 但按钮的颜色保持白色 悬停时颜色恢复正常 单击按钮时仍然具有波纹效果 但当不悬停时 它
  • 应用程序内更新不适用于应用程序包 apk

    我在我的 Android 应用程序中实现了最近推出的应用内更新 API 当我构建 apk 并测试此功能时 它工作正常 我已经上传了带有测试版的更高版本的apk 但是 当我构建应用程序包并将应用程序包上传到内部内部应用程序共享时 永远不会提示
  • 为什么 MSVC 2010 32 位项目链接到 64 位 kernel32.dll?

    我有一个 Win32 32 位 DLL 项目 它的构建和链接没有错误 DLL 无法加载到 32 位进程中 使用 DependencyWalker 我看到 DLL 是 32 位的 但已与 kernel32 msvcr100d ws2 32 和
  • C中的无符号整数[关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 当我运行下面的程序时 它输出类似 109876543210 1 2 3 4 5 6 78
  • 无法在 selenium webdriver 中启动 IE 浏览器

    我已经编写了示例代码来启动IE browser并加载谷歌页面 public class Sample public static void main String args TODO Auto generated method stub S
  • IOS 中获取错误的运营商名称

    我正在开发一个 IOS 应用程序 我的要求是获取移动运营商名称 我使用了以下代码 In h import
  • 正则表达式跳过模式

    Problem 我需要用百分号 替换所有星号 方括号中的星号应被忽略 Example Test public void Replace all asterisks outside the square brackets var input
  • 使用 PDFBox 进行图像旋转

    我对使用 PDFBox 很陌生 我需要的是将带有旋转的图像添加到现有的 PDF 中 我知道如何添加图像 但我的问题是如何旋转图像 我见过一些关于 AffineTransform 和 Matrix 的东西 但我不知道那是什么以及它是如何工作的
  • jQuery 更改(使用淡入淡出动画)悬停时 div 的背景图像

    我正在尝试使用 jQuery 更改悬停时 div 的背景图像 这是我到目前为止所想到的 但是它不起作用 html div class logo div css logo width 300px height 100px background
  • Scipy插值如何将3x3矩阵调整大小/重新采样为5x5?

    EDIT 保罗在下面解决了这个问题 谢谢 我正在尝试将 3x3 矩阵重新采样 升级 为 5x5 用 interpolate interp2d 或 interpolate RectBivariateSpline 或其他有效的方法 填充中间点
  • 在 Android 上录制视频时拍照

    我编写了如下所示的 Android 服务 用于在后台录制前置摄像头 这非常有效 但现在我想在录制时每 5 秒拍一张照片 这有可能吗 当我尝试打开第二个摄像头 在另一个服务中 时 出现错误 public class RecorderServi