JavaCV:将任意视频转码为h264编码的mp4格式视频

这篇具有很好参考价值的文章主要介绍了JavaCV:将任意视频转码为h264编码的mp4格式视频。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

视频工具类

import org.bytedeco.ffmpeg.avcodec.AVCodecParameters;
import org.bytedeco.ffmpeg.avformat.AVFormatContext;
import org.bytedeco.ffmpeg.avformat.AVStream;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.FFmpegLogCallback;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameGrabber;

/**
 * 视频工具类
 * 
 * @author alderaan
 * @version 创建时间:2022年5月10日 下午3:43:18
 *
 */
public class VideoUtil
{
	/**
	 * 视频转码函数(仅转码)
	 * 
	 * @param inputfile  原始视频文件完整路径
	 * @param outputfile 目标视频文件完整保存路径(必须完整文件名,即包含格式后缀,推荐格式后缀为.mp4)
	 * @throws Exception 异常
	 */
	public static void videoConvert(String inputfile, String outputfile) throws Exception
	{
		if (outputfile.lastIndexOf('.') < 0)
		{
			throw new Exception("Error! Output file format undetected!");
		}
		String format = outputfile.substring(outputfile.lastIndexOf('.'));

		FFmpegLogCallback.set();
		Frame frame;
		FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputfile);
		FFmpegFrameRecorder recorder = null;

		try
		{
			System.out.println("开始初始化帧抓取器");

			// 初始化帧抓取器,例如数据结构(时间戳、编码器上下文、帧对象等),
			// 如果入参等于true,还会调用avformat_find_stream_info方法获取流的信息,放入AVFormatContext类型的成员变量oc中
			grabber.start(true);

			System.out.println("帧抓取器初始化完成");

			// grabber.start方法中,初始化的解码器信息存在放在grabber的成员变量oc中
			AVFormatContext avformatcontext = grabber.getFormatContext();

			// 文件内有几个媒体流(一般是视频流+音频流)
			int streamNum = avformatcontext.nb_streams();

			// 没有媒体流就不用继续了
			if (streamNum < 1)
			{
				System.out.println("文件内不存在媒体流");
				throw new Exception("Error! There is no media stream in the file!");
			}

			// 取得视频的帧率
			double framerate = grabber.getVideoFrameRate();

			System.out.printf("视频帧率[%f],视频时长[%d]秒,媒体流数量[%d]\r\n", framerate, avformatcontext.duration() / 1000000,
					avformatcontext.nb_streams());

			// 遍历每一个流,检查其类型
			for (int i = 0; i < streamNum; i++)
			{
				AVStream avstream = avformatcontext.streams(i);
				AVCodecParameters avcodecparameters = avstream.codecpar();
				System.out.printf("流的索引[%d],编码器类型[%d],编码器ID[%d]\r\n", i, avcodecparameters.codec_type(),
						avcodecparameters.codec_id());
			}

			// 视频宽度
			int frameWidth = grabber.getImageWidth();
			// 视频高度
			int frameHeight = grabber.getImageHeight();
			// 音频通道数量
			int audiochannels = grabber.getAudioChannels();

			System.out.printf("视频宽度[%d],视频高度[%d],音频通道数[%d]\r\n", frameWidth, frameHeight, audiochannels);

			recorder = new FFmpegFrameRecorder(outputfile, frameWidth, frameHeight, audiochannels);
			recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);

			recorder.setFormat(format);
			// 使用原始视频的码率,若需要则自行修改码率
			recorder.setVideoBitrate(grabber.getVideoBitrate());
			
			// 一秒内的帧数,帧率
			recorder.setFrameRate(framerate);

			// 两个关键帧之间的帧数
			recorder.setGopSize((int)framerate);

			// 设置音频通道数,与视频源的通道数相等
			recorder.setAudioChannels(grabber.getAudioChannels());

			recorder.start();

			int videoframenum = 0;
			int audioframenum = 0;
			int dataframenum = 0;

			// 持续从视频源取帧
			while (null != (frame = grabber.grab()))
			{
				// 有图像,就把视频帧加一
				if (null != frame.image)
				{
					videoframenum++;
					// 取出的每一帧,都保存到视频
					recorder.record(frame);
				}

				// 有声音,就把音频帧加一
				if (null != frame.samples)
				{
					audioframenum++;
					// 取出的每一帧,都保存到视频
					recorder.record(frame);
				}

				// 有数据,就把数据帧加一
				if (null != frame.data)
				{
					dataframenum++;
				}
			}

			System.out.printf("转码完成,视频帧[%d],音频帧[%d],数据帧[%d]\r\n", videoframenum, audioframenum, dataframenum);

		} catch (Exception e)
		{
			// e.printStackTrace();
			throw e;
		} finally
		{
			if (recorder != null)
			{
				try
				{
					recorder.close();
				} catch (Exception e)
				{
					// System.out.println("recorder.close异常" + e);
					throw e;
				}
			}

			try
			{
				grabber.close();
			} catch (FrameGrabber.Exception e)
			{
				// System.out.println("frameGrabber.close异常" + e);
				throw e;
			}
		}
	}
}

测试类

/**
 * 测试类
 * 
 * @author alderaan
 * @version 创建时间:2022年5月10日 下午3:47:49
 *
 */
public class App
{
	public static void main(String[] args)
	{
		try
		{
			// videoConvert函数,根据outputfile的格式后缀设置转码后的视频格式,推荐使用mp4格式后缀
			VideoUtil.videoConvert("/home/alderaan/test.MOV", "/result.mp4");
		} catch (java.lang.Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("执行完毕!");
	}
}

POM

		<!-- Linux x86_64 使用 -->
		<dependency>
			<groupId>org.bytedeco</groupId>
			<artifactId>javacpp</artifactId>
			<version>1.5.7</version>
		</dependency>
		<dependency>
			<groupId>org.bytedeco</groupId>
			<artifactId>opencv</artifactId>
			<version>4.5.5-1.5.7</version>
			<classifier>linux-x86_64-gpu</classifier>
		</dependency>
		<dependency>
			<groupId>org.bytedeco</groupId>
			<artifactId>openblas</artifactId>
			<version>0.3.19-1.5.7</version>
			<classifier>linux-x86_64</classifier>
		</dependency>
		<dependency>
			<groupId>org.bytedeco</groupId>
			<artifactId>ffmpeg</artifactId>
			<version>5.0-1.5.7</version>
			<classifier>linux-x86_64-gpl</classifier>
		</dependency>
		<!-- Windows x86_64 使用 -->
		<dependency>
			<groupId>org.bytedeco</groupId>
			<artifactId>opencv</artifactId>
			<version>4.5.5-1.5.7</version>
			<classifier>windows-x86_64</classifier>
		</dependency>
		<dependency>
			<groupId>org.bytedeco</groupId>
			<artifactId>openblas</artifactId>
			<version>0.3.19-1.5.7</version>
			<classifier>windows-x86_64</classifier>
		</dependency>
		<dependency>
			<groupId>org.bytedeco</groupId>
			<artifactId>ffmpeg</artifactId>
			<version>5.0-1.5.7</version>
			<classifier>windows-x86_64</classifier>
		</dependency>

文章来源地址https://www.toymoban.com/news/detail-589353.html

到了这里,关于JavaCV:将任意视频转码为h264编码的mp4格式视频的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python ffmpeg将mp4文件实时转码为ts,并指定pid等信息,输出到udp

    要将MP4文件实时转码为TS格式,并将PID等信息指定为UDP输出,可以使用 subprocess 模块和ffmpeg命令行工具来实现。以下是一个示例代码,用于实时转码并将输出发送到UDP服务器: 在上述代码中,我们首先定义了输入文件、UDP服务器地址和PID等信息。然后,我们使用 subprocess.Pop

    2024年01月22日
    浏览(62)
  • 9i物联网浏览器(cef_114.2.120&114.2.100,支持H264视频mp3,mp4)WinForm-CefSharp(5735分支)多媒体版本体验

    更新:2023.6.25 版本: Cef_114.2.110和114.2.100 +chromium- 114.0.5735.134 的32位和64位 说明:支持图片,mp3,mp4(H264)多媒体 测试环境:windows server 2019(其他环境没测,一般问题.NET4.5.2+及vc++运行库问题) 测试网址:www.html5test.com 声明 :本博是交流学习的内容,应用案例定制版浏览器

    2024年02月16日
    浏览(54)
  • [解决思路]关于h264裸流合成mp4时时间戳添加问题

            使用GPU编码(Opencv)生成的h264视频片段中不包含时间戳信息,且含有B帧,直接合成mp4后会导致播放出现问题(瞬间播放完成)。因此,在合成时需要手动添加时间戳。         发现生成的视频会 瞬间播放完成 后,意识到是时间戳的问题,检查时间戳代码:        

    2024年01月21日
    浏览(41)
  • JAVA实现H264视频流推送到RTSP、RTMP服务----JavaCV

    前提: 1.准备好rtsp、rtmp服务 2.准备好视频流接收程序 基本思路是:启动两个线程,线程1接收视频流,线程2使用JavaCV将视频流推送到RTSP、RTMP服务,两者之间使用管道流进行通信。线程2接收到视频流后的具体操作:启动grabber接收视频流并捕获视频帧,然后启动recoder将捕获的

    2024年02月11日
    浏览(59)
  • 视频编码(H264编码)

    基本步骤:    1、打开编码器          2、转换NV12到YUV420,这是因为FFmpeg的x264编码器只支持YUV420          3、准备编码数据AVFrame         创建frame:  创建AVPacket: AVPacket* pck = av_packet_alloc(); 4、H264编码       avcodec_send_frame(#AVCodecContext *avctx#, #const AVFrame *frame#)    

    2024年02月03日
    浏览(47)
  • 音视频——视频流H264编码格式

    我们了解了什么是宏快,宏快作为压缩视频的最小的一部分,需要被组织,然后在网络之间做相互传输。 H264更深层次 —》宏块 太浅了 ​ 如果单纯的用 宏快 来发送数据是 杂乱无章 的,就好像在没有 集装箱 出现之前,货物总是随意被堆放到船上。 上货(编码),下货是非

    2024年02月15日
    浏览(60)
  • 视频编码流程 YUV数据编码为H264数据

    视频编码时,设置编码器上下文参数有:码率,宽,高,格式,帧率等 frame设置:宽,高,格式 然后计算一帧的数据:宽 * 高 * 格式占用字节数 通常使用av_image_get_buffer_size来计算 av_opt_set就是用来设置参数的 preset preset参数是一个权衡编码速度和压缩率的参数,编码速度越慢,压缩率越高 参数

    2024年02月13日
    浏览(45)
  • 视频一键转码:批量转换MP4视频的技巧

    随着数字媒体设备的普及,视频文件在生活中扮演着越来越重要的角色。而在处理视频文件时,有时需要将其转换为不同的格式以适应不同的需求。其中,MP4格式因其通用性和高质量而备受青睐。本文详解云炫AI智剪如何一键转码的技巧,帮助批量转换MP4视频。 步骤1、在云炫

    2024年02月22日
    浏览(48)
  • 音视频处理 ffmpeg中级开发 H264编码

    libavcodec/avcodec.h 常用的数据结构 AVCodec 编码器结构体 AVCodecContext 编码器上下文 AVFrame 解码后的帧 结构体内存的分配和释放 av_frame_alloc 申请 av_frame_free() 释放 avcodec_alloc_context3() 创建编码器上下文 avcodec_free_context() 释放编码器上下文 解码步骤 avcodec_find_decoder 查找解码器 avcod

    2024年02月01日
    浏览(86)
  • 【解决】萤石云接入视频报错视频编码类型非H264

    说在前面 项目视频监控设备接入了萤石云,部分视频无法正常加载,报错页面如下: 原因分析 视频监控视频编码目前有H265和H264两种,萤石云仅支持H264的编码格式,所以对于接入的视频流才会出现这种错误。 解决方案 方案一:如果你能接触到项目部网络,可以参考萤石云

    2024年02月14日
    浏览(74)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包