如果通过javacv来调用ffmpeg解析mp4视频为m3u8,内存式hls切片.通过流的方式来保存?

首先创建一个springboot的脚手架

按图所示
在这里插入图片描述
选一个web容器启动就行了。在这里插入图片描述

项目结构如下

在这里插入图片描述
info保存的是

  • 外部访问key文件的地址
  • 执行时访问key的地址
  • 密钥
    在这里插入图片描述
    key保存的是加密key
    在这里插入图片描述
    pom文件如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>ffmpeg-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ffmpeg-demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <javacv.version>1.5.4</javacv.version>
        <ffmpeg.version>4.3.1-1.5.4</ffmpeg.version>
    </properties>

    <dependencies>

        <!--web 模块 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <!--排除tomcat依赖 -->
                <exclusion>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--undertow容器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--      javacv 和 ffmpeg的依赖包      -->
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>${javacv.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.bytedeco</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>${ffmpeg.version}</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.6.5</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

编写一个处理类和一个controller

package com.example.ffmpeg.demo.processor;

import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author : xuansy
 * @version : 1.0
 * @date : 2021/5/21 22:46
 * @project_name: ffmpeg-demo
 * @package_name : com.example.ffmpeg.demo.processor
 * @name: FFmpegProcessor
 * @email: 1292798418@qq.com
 * @description :
 */
public class FFmpegProcessor {

	/**
	* 这个方法的url地址都必须是一样的类型 同为post
	*/
    public static void convertMediaToM3u8ByHttp(InputStream inputStream, String m3u8Url, String infoUrl) throws IOException {

        avutil.av_log_set_level(avutil.AV_LOG_INFO);
        FFmpegLogCallback.set();

        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputStream);
        grabber.start();

        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(m3u8Url, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());

        recorder.setFormat("hls");
        recorder.setOption("hls_time", "5");
        recorder.setOption("hls_list_size", "0");
        recorder.setOption("hls_flags", "delete_segments");
        recorder.setOption("hls_delete_threshold", "1");
        recorder.setOption("hls_segment_type", "mpegts");
        recorder.setOption("hls_segment_filename", "http://localhost:8080/upload/test-%d.ts");
        recorder.setOption("hls_key_info_file", infoUrl);

        // http属性
        recorder.setOption("method", "POST");

        recorder.setFrameRate(25);
        recorder.setGopSize(2 * 25);
        recorder.setVideoQuality(1.0);
        recorder.setVideoBitrate(10 * 1024);
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        recorder.start();

        Frame frame;
        while ((frame = grabber.grabImage()) != null) {
            try {
                recorder.record(frame);
            } catch (FrameRecorder.Exception e) {
                e.printStackTrace();
            }
        }
        recorder.setTimestamp(grabber.getTimestamp());
        recorder.close();
        grabber.close();
    }

}

只做测试,写在一个controller

package com.example.ffmpeg.demo.controller;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import com.example.ffmpeg.demo.processor.FFmpegProcessor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @author : xuansy
 * @version : 1.0
 * @date : 2021/5/21 22:45
 * @project_name: ffmpeg-demo
 * @package_name : com.example.ffmpeg.demo.controller
 * @name: TestController
 * @email: 1292798418@qq.com
 * @description :
 */
@RestController
public class TestController {

    /**
     * 目录路径,这个路径需要包含test.info文件,test.key文件和test.mp4文件
     */
    private static final String PATH = "D:\\test\\";

    @PostMapping("uploadToM3u8")
    public void uploadToM3u8() throws Exception {
        FileInputStream inputStream = new FileInputStream(PATH + "test.mp4");
        String m3u8Url = "http://localhost:8080/upload/test.m3u8";
        String infoUrl = "http://localhost:8080/preview/test.info";
        FFmpegProcessor.convertMediaToM3u8ByHttp(inputStream, m3u8Url, infoUrl);
    }

    @PostMapping("upload/{fileName}")
    public void upload(HttpServletRequest request, @PathVariable("fileName") String fileName) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        FileWriter writer = new FileWriter(PATH + fileName);
        writer.writeFromStream(inputStream);
        IoUtil.close(inputStream);
    }

    /**
     * 预览加密文件
     */
    @PostMapping("preview/{fileName}")
    public void preview(@PathVariable("fileName") String fileName, HttpServletResponse response) throws IOException {
        FileReader fileReader = new FileReader(PATH + fileName);
        fileReader.writeToStream(response.getOutputStream());
    }

    /**
     * 预览加密文件
     */
    @GetMapping("download/{fileName}")
    public void download(@PathVariable("fileName") String fileName, HttpServletResponse response) throws IOException {
        FileReader fileReader = new FileReader(PATH + fileName);
        fileReader.writeToStream(response.getOutputStream());
    }

}

启动springboot,执行下面图形操作,生成http测试文件
在这里插入图片描述
在这里插入图片描述
点击执行即可,等待http请求执行完,那么就可以看到目录下生成了m3u8文件和ts文件。

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
此时有个地方我们需要修改下,那就是m3u8中的密钥http请求地址,因为我们的例子,都是post所以我们一会浏览器测试的时候方法不支持,我们直接删除前面的,
在这里插入图片描述
这样请求key的时候默认会走和m3u8请求的地址前缀一样。
接下来打开chrome浏览器,安装Play HLS M3u8 插件,如果没有,那么自己找个离线可以播m3u8的软件即可。
在这里插入图片描述
复制http://localhost:8080/download/test.m3u8到浏览器地址栏访问即可。
在这里插入图片描述
此时就算视频切片成m3u8文件,并加密了。感谢大家观看。

以下是一个简单的 Java 程序,它使用 FFmpeg 库来拉取 RTSP 视频流并将其解码为 H.264 格。 ```java import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.Java2DFrameConverter; import org.bytedeco.javacv.OpenCVFrameConverter; public class RTSPStreamDecoder { public static void main(String[] args) { String rtspUrl = "rtsp://example.com/stream"; // RTSP 视频流的 URL int frameWidth = 640; int frameHeight = 480; int videoCodec = 28; // H.264 编码器的 ID // 创建 FFmpegFrameGrabber 对象 FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(rtspUrl); // 设置视频流的宽度和高度 grabber.setImageWidth(frameWidth); grabber.setImageHeight(frameHeight); // 设置视频编解码器 grabber.setVideoCodec(videoCodec); try { // 开始捕获视频帧 grabber.start(); // 创建帧转换器 Java2DFrameConverter converter1 = new Java2DFrameConverter(); OpenCVFrameConverter.ToMat converter2 = new OpenCVFrameConverter.ToMat(); // 循环读取视频帧并进行解码和转换 while (true) { Frame frame = grabber.grab(); // 判断是否到达视频流的末尾 if (frame == null) { break; } // 将帧转换为 BufferedImage BufferedImage image = converter1.convert(frame); // 将 BufferedImage 转换为 Mat Mat mat = converter2.convertToMat(frame); // 在这里可以对视频帧进行处理,例如进行图像识别、人脸检测等 // TODO: 将处理后的视频帧转码为 H.264 格保存到文件中 } // 停止捕获视频帧 grabber.stop(); } catch (Exception e) { e.printStackTrace(); } } } ``` 请注意,此程序只读取并解码 RTSP 视频流,并没有将其转码为 H.264 格保存到文件中。如果您需要将视频流转码为 H.264 格保存到文件中,请使用 FFmpeg 库的命令行工具或其他第三方库来实现。
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值