JavaCV录制屏幕(窗口)和系统声音,内录

JavaCV录屏,云游戏串流的一个模块

dshow采集音频,因为暂时不会别的更好的方法,gdigrab采集视频也是因为效果比dshow好但是不会更好的,

采用多线程可以避免出现缓冲溢出的情况

[dshow @ 000001c47844cf80] real-time buffer [virtual-audio-capturer] [audio input] too full or near too full (87% of size: 3041280 [rtbufsize parameter])! frame dropped!
dshow录屏插件下载地址:

https://download.csdn.net/download/qq_46372033/87423453icon-default.png?t=N0U7https://download.csdn.net/download/qq_46372033/87423453

下载运行安装即可,可以全屏录制视频也可录制音频

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;

public class AV_Thread {

    public static void main(String[] args) throws FFmpegFrameGrabber.Exception, FFmpegFrameRecorder.Exception {
        //初始化
        FFmpegFrameGrabber a_grabber = new FFmpegFrameGrabber("audio=virtual-audio-capturer");
        a_grabber.setFormat("dshow");
        a_grabber.start();
        System.out.println("音频抓取器初始化完成");

        FFmpegFrameGrabber v_grabber = new FFmpegFrameGrabber("desktop");
        v_grabber.setFormat("gdigrab");
        v_grabber.setFrameRate(30);
        v_grabber.start();
        System.out.println("视频抓取器初始化完成");

        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("src/main/resources/video/AV_Thread.flv",
                v_grabber.getImageWidth(),
                v_grabber.getImageHeight());
        recorder.setPixelFormat(avutil.AV_PIX_FMT_NV12);//intel核显编码仅支持nv12和p010le
        recorder.setVideoCodecName("h264_qsv");//硬件编码h264
        recorder.setVideoBitrate(2000 * 1000);//码率,这里是2000kb/s
        recorder.setMaxBFrames(0);//禁用B帧,降低延迟
        recorder.setFormat("flv");//封装格式
        recorder.setGopSize(30 * 3);//关键帧间距
        recorder.setFrameRate(30);//帧率
        recorder.setInterleaved(true);
        recorder.setVideoOption("tune", "zerolatency");//设置预设,zerolatency表示零延迟,适用于实时视频会议
        //ultrafast,superfast,veryfast,faster,fast,medium,slow,slower,veryslow
        recorder.setVideoOption("preset", "veryfast");//编码速度,gpu编码最快是veryfast
        recorder.setVideoOption("crf", "28");//动态码率,取值范围0-51,建议17-28,17或18即可获得视觉上与无损无区别的画面,但算法上经过有损压缩

        recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);//编码格式
        recorder.setAudioBitrate(320 * 1000);//固定码率
        recorder.setAudioOption("vbr", "1");//可变比特率,1-5,1最低,5最高
        recorder.setAudioChannels(2);//声道
        recorder.setSampleRate(48000);//采样率
        recorder.start();
        System.out.println("录制器初始化完成");


        //创建两个线程
        Thread v_Record = new Thread(() -> {
            System.out.println("视频线程启动");
            Frame a_frame = null;
            while (true) {
                try {
                    if ((a_frame = a_grabber.grabSamples()) != null) {
                        recorder.recordSamples(48000, 2, a_frame.samples);
                    } else {
                        break;
                    }
                } catch (FFmpegFrameGrabber.Exception e) {
                    throw new RuntimeException(e);
                } catch (FFmpegFrameRecorder.Exception e) {
                    throw new RuntimeException(e);
                }

            }
        });
        Thread a_Record = new Thread(() -> {
            System.out.println("音频线程启动");
            Frame v_frame = null;
            while (true) {
                try {
                    if ((v_frame = v_grabber.grabImage()) != null) {
                        recorder.recordImage(v_frame.imageWidth,
                                v_frame.imageHeight,
                                v_frame.imageDepth,
                                v_frame.imageChannels,
                                v_frame.imageStride,
                                v_grabber.getPixelFormat(),
                                v_frame.image);
                    } else {
                        break;
                    }
                } catch (FFmpegFrameGrabber.Exception e) {
                    throw new RuntimeException(e);
                } catch (FFmpegFrameRecorder.Exception e) {
                    throw new RuntimeException(e);
                }
            }
        });

        //启动执行
        a_Record.start();
        v_Record.start();
    }
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
注:下文中的 *** 代表文件名中的版本号。 # 【javacv-***.jar中文文档.zip】 中包含: 中文文档:【javacv-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【javacv-***.jar下载地址(官方地址+国内镜像地址).txt】 Maven依赖:【javacv-***.jar Maven依赖信息(可用于项目pom.xml).txt】 Gradle依赖:【javacv-***.jar Gradle依赖信息(可用于项目build.gradle).txt】 源代码下载地址:【javacv-***-sources.jar下载地址(官方地址+国内镜像地址).txt】 # 本文件关键字: javacv-***.jar中文文档.zip,java,javacv-***.jar,org.bytedeco,javacv,***,cl.eye,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,bytedeco,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【javacv-***.jar中文文档.zip】,再解压其中的 【javacv-***-javadoc-API文档-中文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件; # Maven依赖: ``` <dependency> <groupId>org.bytedeco</groupId> <artifactId>javacv</artifactId> <version>***</version> </dependency> ``` # Gradle依赖: ``` Gradle: implementation group: 'org.bytedeco', name: 'javacv', version: '***' Gradle (Short): implementation 'org.bytedeco:javacv:***' Gradle (Kotlin): implementation("org.bytedeco:javacv:***") ``` # 含有的 Java package(包): ``` cl.eye org.bytedeco.javacv ``` # 含有的 Java class(类)(此处仅列举3个): ``` cl.eye.CLCamera org.bytedeco.javacv.AndroidFrameConverter org.bytedeco.javacv.BaseChildSettings ...... ```
你可以使用JavaCV库来录制Android设备的视频。以下是一个简单的示例代码: ```java import org.bytedeco.javacpp.Loader; import org.bytedeco.javacv.FFmpegFrameRecorder; import org.bytedeco.opencv.opencv_core.IplImage; import android.hardware.Camera; import android.view.SurfaceHolder; public class Recorder implements SurfaceHolder.Callback, Camera.PreviewCallback { private FFmpegFrameRecorder recorder; private boolean recording = false; @Override public void surfaceCreated(SurfaceHolder holder) { // 初始化recorder recorder = new FFmpegFrameRecorder("/sdcard/video.mp4", 640, 480, 1); recorder.setFormat("mp4"); recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); recorder.setFrameRate(30); recorder.setPixelFormat(org.bytedeco.opencv.global.avutil.AV_PIX_FMT_YUV420P); // 开始录制 try { recorder.start(); recording = true; } catch (FFmpegFrameRecorder.Exception e) { e.printStackTrace(); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { // 停止录制 try { recording = false; recorder.stop(); recorder.release(); } catch (FFmpegFrameRecorder.Exception e) { e.printStackTrace(); } } @Override public void onPreviewFrame(byte[] data, Camera camera) { if (recording) { IplImage image = IplImage.create(640, 480, org.bytedeco.opencv.global.avutil.AV_PIX_FMT_NV21, 1); image.getByteBuffer().put(data); try { recorder.record(image); } catch (FFmpegFrameRecorder.Exception e) { e.printStackTrace(); } } } } ``` 在这个示例中,我们使用`SurfaceHolder`来创建一个视频录制器,并在`Camera.PreviewCallback`回调中将预览帧入到视频文件中。你需要在你的Android应用程序中创建一个`SurfaceView`或`TextureView`,并将其与`Recorder`类关联。 请注意,这只是一个简单的示例代码。在实际应用中,你可能需要处理更多的异常情况,并进行更多的性能优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值