FFmpeg+javacpp+javacv使用

FFmpeg+javacpp+javacv使用

  • Bytedeco官网案例
  • 1、导入opencv、ffmpeg依赖包
  • 2、FFmpeg 数据结构
    • 2.1 AVFormatContext 格式化I/O上下文
      • 2.1.1 metadata
      • 2.1.2 Duration、start、bitrate等其他信息
      • 2.1.3 dump信息

Bytedeco
GitHub:javacpp

Bytedeco官网案例

FFmpeg – [示例用法] [API] – 一个完整的跨平台解决方案,用于录制、转换和流式传输音频和视频
FFmpeg 6.1.1 http://ffmpeg.org/ 关于 FFmpeg
JavaCPP Presets for FFmpeg 6.1.1-1.5.10 API
javacv:https://github.com/bytedeco/javacv


坑哧吭坑: 这可能是最详细的javaCV-FFmpeg防踩坑入门了
javaCV入门指南
雷霄骅(leixiaohua1020)的专栏 FFmpeg
FFmpeg - 打造一款万能的音乐播放器

1、导入opencv、ffmpeg依赖包

ext {
    javacvVersion = '1.5.9'
    ffmpegVersion = '6.0'
    windowsVersion = 'windows-x86_64'
}

dependencies {
    /* javacv + FFmpeg */
    // implementation group: 'org.bytedeco', name: 'javacv-platform', version: "$javacvVersion"
    implementation "org.bytedeco:javacpp:${javacvVersion}:${windowsVersion}"
    implementation "org.bytedeco:javacv:${javacvVersion}"
    implementation "org.bytedeco:ffmpeg:${ffmpegVersion}-${javacvVersion}"
    implementation "org.bytedeco:ffmpeg:${ffmpegVersion}-${javacvVersion}:${windowsVersion}"

    testImplementation platform('org.junit:junit-bom:5.9.1')
    testImplementation 'org.junit.jupiter:junit-jupiter'
}

在这里插入图片描述

2、FFmpeg 数据结构

2.1 AVFormatContext 格式化I/O上下文

在这里插入图片描述

这是FFMpeg中最为基本的一个结构,是其他所有结构的根,是一个多媒体文件或流的根本抽象。其中nb_streamsstreams所表示的AVStream结构指针数组包含了所有内嵌媒体流的描述;iformatoformat指向对应的demuxer和muxer指针;pb则指向一个控制底层数据读写的ByteIOContext结构。 start_timeduration是从streams数组的各个AVStream中推断出的多媒体文件的起始时间和长度,以微妙为单位。 通常,这个结构由av_open_input_file在内部创建并以缺省值初始化部分成员。但是,如果调用者希望自己创建该结构,则需要显式为该结构的一些成员置缺省值;如果没有缺省值的话,会导致之后的动作产生异常。

String url = "C:\\Users\\Administrator\\Desktop\\Let Me Down Slowly.mp3";
// 解封装上下文
AVFormatContext pFormatCtx = new AVFormatContext(null);
if (null == pFormatCtx) {
    XLog.e("获取解封装上下文失败");
    return;
}

// 打开流媒体
if (avformat_open_input(pFormatCtx, url, null, null) != 0) {
    XLog.e("打开媒体失败");
    return;
}

// 读取流媒体数据,以获得流的信息
if (avformat_find_stream_info(pFormatCtx, (PointerPointer<Pointer>) null) < 0) {
    XLog.e("获得媒体流信息失败");
    return;
}

2.1.1 metadata

在这里插入图片描述

AVDictionaryEntry tag = null;
tag = av_dict_get(pFormatCtx.metadata(), "", tag, AV_DICT_IGNORE_SUFFIX);
while (tag != null) {
    XLog.d("tag.key : " + tag.key().getString() + "; tag.value : " + tag.value().getString());
    tag = av_dict_get(pFormatCtx.metadata(), "", tag, AV_DICT_IGNORE_SUFFIX);
}

在这里插入图片描述

2.1.2 Duration、start、bitrate等其他信息

时间基准 public static final int AV_TIME_BASE = 1000000;
在这里插入图片描述

XLog.d("pFormatCtx url() = " + pFormatCtx.url().getString());
XLog.d("pFormatCtx start_time() = " + pFormatCtx.start_time());
XLog.d("pFormatCtx duration() = " + pFormatCtx.duration());
XLog.d("pFormatCtx bit_rate() = " + pFormatCtx.bit_rate());

在这里插入图片描述

2.1.3 dump信息

av_dump_format(pFormatCtx, 0, url, 0);
在这里插入图片描述

源码ffmpeg-6.0\libavformat\dump.c

void av_dump_format(AVFormatContext *ic, int index,
                    const char *url, int is_output)
{
    int i;
    uint8_t *printed = ic->nb_streams ? av_mallocz(ic->nb_streams) : NULL;
    if (ic->nb_streams && !printed)
        return;

    av_log(NULL, AV_LOG_INFO, "%s #%d, %s, %s '%s':\n",
           is_output ? "Output" : "Input",
           index,
           is_output ? ic->oformat->name : ic->iformat->name,
           is_output ? "to" : "from", url);
    dump_metadata(NULL, ic->metadata, "  ");

    if (!is_output) {
        av_log(NULL, AV_LOG_INFO, "  Duration: ");
        if (ic->duration != AV_NOPTS_VALUE) {
            int64_t hours, mins, secs, us;
            int64_t duration = ic->duration + (ic->duration <= INT64_MAX - 5000 ? 5000 : 0);
            secs  = duration / AV_TIME_BASE;
            us    = duration % AV_TIME_BASE;
            mins  = secs / 60;
            secs %= 60;
            hours = mins / 60;
            mins %= 60;
            av_log(NULL, AV_LOG_INFO, "%02"PRId64":%02"PRId64":%02"PRId64".%02"PRId64"", hours, mins, secs,
                   (100 * us) / AV_TIME_BASE);
        } else {
            av_log(NULL, AV_LOG_INFO, "N/A");
        }
        if (ic->start_time != AV_NOPTS_VALUE) {
            int secs, us;
            av_log(NULL, AV_LOG_INFO, ", start: ");
            secs = llabs(ic->start_time / AV_TIME_BASE);
            us   = llabs(ic->start_time % AV_TIME_BASE);
            av_log(NULL, AV_LOG_INFO, "%s%d.%06d",
                   ic->start_time >= 0 ? "" : "-",
                   secs,
                   (int) av_rescale(us, 1000000, AV_TIME_BASE));
        }
        av_log(NULL, AV_LOG_INFO, ", bitrate: ");
        if (ic->bit_rate)
            av_log(NULL, AV_LOG_INFO, "%"PRId64" kb/s", ic->bit_rate / 1000);
        else
            av_log(NULL, AV_LOG_INFO, "N/A");
        av_log(NULL, AV_LOG_INFO, "\n");
    }

    if (ic->nb_chapters)
        av_log(NULL, AV_LOG_INFO, "  Chapters:\n");
    for (i = 0; i < ic->nb_chapters; i++) {
        const AVChapter *ch = ic->chapters[i];
        av_log(NULL, AV_LOG_INFO, "    Chapter #%d:%d: ", index, i);
        av_log(NULL, AV_LOG_INFO,
               "start %f, ", ch->start * av_q2d(ch->time_base));
        av_log(NULL, AV_LOG_INFO,
               "end %f\n", ch->end * av_q2d(ch->time_base));

        dump_metadata(NULL, ch->metadata, "      ");
    }

    if (ic->nb_programs) {
        int j, k, total = 0;
        for (j = 0; j < ic->nb_programs; j++) {
            const AVProgram *program = ic->programs[j];
            const AVDictionaryEntry *name = av_dict_get(program->metadata,
                                                        "name", NULL, 0);
            av_log(NULL, AV_LOG_INFO, "  Program %d %s\n", program->id,
                   name ? name->value : "");
            dump_metadata(NULL, program->metadata, "    ");
            for (k = 0; k < program->nb_stream_indexes; k++) {
                dump_stream_format(ic, program->stream_index[k],
                                   index, is_output);
                printed[program->stream_index[k]] = 1;
            }
            total += program->nb_stream_indexes;
        }
        if (total < ic->nb_streams)
            av_log(NULL, AV_LOG_INFO, "  No Program\n");
    }

    for (i = 0; i < ic->nb_streams; i++)
        if (!printed[i])
            dump_stream_format(ic, i, index, is_output);

    av_free(printed);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/732605.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flutter图像编辑器应用:创造生动美丽的照片体验

介绍 引言 想象一下&#xff0c;在一个阳光明媚的下午&#xff0c;与家人或朋友漫步在风景如画的街道上。拿出手机&#xff0c;迫不及待地捕捉这一刻的美好&#xff0c;按下快门&#xff0c;留下了一张充满回忆的照片。 然而&#xff0c;回到家后发现照片的亮度有些偏暗&…

【机器学习】正则卷积群理论及Python代码实现

1. 引言 1.1.卷积神经网络CNN 卷积神经网络&#xff08;CNN&#xff09;的数学模型是深度学习中用于处理图像和其他高维数据的关键组成部分。那么&#xff0c;CNN究竟是什么呢&#xff1f; 总结起来&#xff0c;CNN网络主要完成以下操作&#xff1a; 卷积操作&#xff08;Co…

Android记录3--ExpandableListView使用+获取SIM卡状态信息

布局文件&#xff1a; /SIM_Card_Demo/res/layout/inbox.xml <LinearLayout xmlns:android“http://schemas.android.com/apk/res/android” xmlns:tools“http://schemas.android.com/tools” android:layout_width“match_parent” android:layout_height“match_par…

Docker部署Nginx1.21.5(保姆级图文教程)

系列文章目录 Docker部署Nginx1.21.5&#xff08;保姆级图文教程&#xff09; Docker部署MySQL8.3.0&#xff08;保姆级图文教程&#xff09; 文章目录 一、环境二、拉取镜像2.1 查找 Docker Hub 上的 nginx 镜像2.2 拉取Nginx镜像2.3 查看Nginx镜像 三、在宿主机创建目录四、启…

Python爬虫基础以及示例讲解

爬虫简介 网络爬虫 爬虫指在使用程序模拟浏览器向服务端发出网络请求&#xff0c;以便获取服务端返回的内容。 但这些内容可能涉及到一些机密信息&#xff0c;所以爬虫领域目前来讲是属于灰色领域&#xff0c;切勿违法犯罪。 爬虫本身作为一门技术没有任何问题&#xff0c;关…

【FreeRTOS】创建任务_使用任务参数

参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》 文章目录 前言编写任务函数创建任务任务保护措施写了个bug疑问遗留问题效果freertos.c 学习链接 前言 配套源码&#xff1a;06_create_task_use_params 我们创建3个任务&#xff0c;使用同一个函数&#xff0c;但是在L…

Master PDF Editor v5 解锁版安装教程(小巧多功能PDF )

前言 Master PDF Editor&#xff0c;小巧的多功能PDF编辑器&#xff0c;轻松查看&#xff0c;创建&#xff0c;修改&#xff0c;批注&#xff0c;签名&#xff0c;扫描&#xff0c;OCR和打印PDF文档。高级注释工具&#xff0c;可以添加任意便笺指示对象突出显示&#xff0c;加…

c++中从父类继承的属性在子类内存中如何显示?

目录 一、继承概念 二、示例 三、结论 一、继承概念 在C中&#xff0c;继承是面向对象编程的一个重要特性&#xff0c;它允许一个类&#xff08;称为派生类或子类&#xff09;继承另一个类&#xff08;称为基类或父类&#xff09;的成员&#xff08;包括数据成员和成员函数…

数据结构:为什么说链表是顺序表的升级版(c语言实现)

前言&#xff1a; 我们在之前的几篇文章中详细的讲解了顺序表的特点&#xff0c;增删改查操作和动态顺序表的优点&#xff0c;并使用顺序表的底层结构实现了通讯录项目&#xff0c;似乎顺序表是一个非常完美的数据结构&#xff0c;它可以实现按照需求实现增删查改&#xff0c;对…

由于bug造成truncate table卡住问题

客户反应truncate table卡主&#xff0c;检查awr发现多个truncate在awr报告期内一直没执行完&#xff0c;如下&#xff1a; 检查ash&#xff0c;truncate table表的等待事件都是“enq: RO - fast object reuse”和“local write wait” 查找“enq: RO - fast object reuse”&am…

2024年能源电力行业CRM研究报告

中国能源电力行业属于大制造业的重要组成部分&#xff0c;在国民经济中的地位举足轻重。据统计&#xff0c;近十年来能源电力行业的整体投资呈现出增长趋势&#xff0c;尤其是“十四五”期间增长显著&#xff0c;2022年全国主要电力企业共完成投资12470亿元&#xff0c;同比增长…

Nuxt3 [Vue warn]: Hydration node mismatch:【解决方案】

[Vue warn]: Hydration node mismatch: 水合节点不匹配 Server rendered element contains more child nodes than client vdom. 服务器呈现的元素包含的子节点多于客户端vdom。 这个问题解决起来也很好解决&#xff0c;看这个问题是怎么出来的&#xff0c;看代码&#xff1a;…

vs工程添加属性表

一、简介 1、 vs工程属性表以&#xff08;.props&#xff09;为后缀 2、 作用&#xff1a;当多个工程需要配置很多相同的属性配置时方便同步&#xff0c;比如多个工程需要链接相同的头文件&#xff0c;库文件&#xff0c;输出路径&#xff0c;中间目录等 3、本章内容测试环境&a…

Mybatis框架的缓存

Mybatis框架的缓存 一.为什么使用缓存 缓存(cache&#xff09;的作用是为了减去数据库的压力&#xff0c;提高查询性能。缓存实现的 原理是从数据库中查询出来的对象在使用完后不要销毁&#xff0c;而是存储在内存&#xff08;缓存&#xff09; 中&#xff0c;当再次需要获取…

做好海外ASO优化的7大核心要素你了解几个?

海外App进行ASO优化时&#xff0c;需要综合考虑多个方面以确保应用在应用商店中获得更高的曝光率和下载量。以下是一些关键的ASO优化步骤&#xff0c;结合参考文章中的相关信息进行详细阐述&#xff1a; 1.关键词优化 调研目标市场的用户行为和检索习惯&#xff0c;挖掘与应用…

Java和C语言中基础概念中的区别有哪些?

Java和C语言中基础概念中的区别有哪些&#xff1f; 标识符数据类型运算符加号%号& 和 | 关系表达式函数声明代码规范数组 以下是Java和C语言在一些基础概念中的区别&#xff08;不包含面向对象等的高级知识&#xff09; 标识符 在Java中&#xff0c;标识符可以由数字、字母…

opencv中文路径问题

目的 在windows系统上&#xff0c;就是直接用QT的utf8编码作为图片路径用在opencv读取或者写入函数&#xff0c;在路径当中含有中文时&#xff0c;会提示编码错误。 就是解决opencv中的中文路径的问题。 情况 代码如下&#xff1a; #pragma execution_character_set("…

Ubuntu系统通过GRUB引导菜单进入恢复模式修改账户密码

当在Ubuntu系统中忘记了账户密码时&#xff0c;有几种方法可以破解或重置密码。 本指引文档方法&#xff1a;通过GRUB引导菜单进入恢复模式 实践环境为&#xff1a;20.04.6 LTS (Focal Fossa) 1. 重启Ubuntu系统&#xff1a;首先&#xff0c;你需要重启你的Ubuntu系统。 2. …

NSSCTF-Web题目14

目录 [CISCN 2019华东南]Web11和[NISACTF 2022]midlevel 1、题目 2、知识点 3、思路 [HDCTF 2023]SearchMaster 1、题目 2、知识点 3、思路 [CISCN 2019华东南]Web11和[NISACTF 2022]midlevel 这两道题目一样 1、题目 2、知识点 SSTI&#xff08;服务端模板注入漏洞&…

Vue74-路由传参2

一、$route中的params参数 二、在配置路由的index.js文件中&#xff0c;声明传参 占位符用的什么名字&#xff0c;params里面的key就是什么。 三、<router-link>标签中传参 3-1、to字符串写法 3-2、to的对象写法 注意&#xff1a;若是用params携带参数&#xff0c;不…