IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java -- 视频压缩(返回压缩后的base64字符串) -> 正文阅读

[Java知识库]Java -- 视频压缩(返回压缩后的base64字符串)

前言:

  • 压缩时间较长, 10M压缩至1M大概需要2~3秒, 不怎么失帧;
  • Demo中返回base64字符串, 可根据自己需求改返回值类型;

环境:

  • JDK 1.8
  • IDEA 2021.3

具体请看代码:

注意:?

  • Window环境和Linux环境需要引用不同的包,建议都引用;?
  • 如果是32位,请把64改为32;
        <dependency>
            <groupId>ws.schild</groupId>
            <artifactId>jave-core</artifactId>
            <version>2.7.3</version>
        </dependency>

        <dependency>
            <groupId>ws.schild</groupId>
            <artifactId>jave-nativebin-win64</artifactId>
            <version>2.7.3</version>
        </dependency>
        <dependency>
            <groupId>ws.schild</groupId>
            <artifactId>jave-nativebin-linux64</artifactId>
            <version>2.7.3</version>
        </dependency>
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;

@RestController
public class DemoController {

    /** 01_main方法测试 */
    public static void main(String[] args) {
        try {
            File file = new File("C:/原视频.mp4");
            String s = VideoUtil.compressVideoByFile(file);
            System.out.println(s);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /** 02_项目中测试 */
    @PostMapping("/test/compressVideo")
    public  String getParams(MultipartFile file){
        try {
            String s = VideoUtil.compressVideoByMultipartFile(file);
            System.out.println(s);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "成功";
    }
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import ws.schild.jave.*;
import java.io.*;
import java.util.*;

/**
 * 视频工具类
 */
@Slf4j
public class VideoUtil {

    /**
     *  压缩视频,返回base64;
     *  接收MultipartFile格式文件;
     * @param multipartFile
     * @return
     * @throws Exception
     */
    public static String compressVideoByMultipartFile(MultipartFile multipartFile) throws Exception {
        File sourceFile = MultipartFileToFile(multipartFile);
        return compressVideoByFile(sourceFile);
    }

    /**
     * 压缩视频,返回base64字符串
     * sourceFile: 源文件;
     */
    public static String compressVideoByFile(File sourceFile) throws Exception {
        String fileName = sourceFile.getName();
        File targetFile = new File(System.currentTimeMillis() + fileName.substring(fileName.lastIndexOf(".")));
        //参数:
        int maxBitRate = 128000; //设置最大值:比特率越高,清晰度/音质越好
        int maxSamplingRate = 44100; //设置编码时候的音量值,未设置为0,如果256,则音量值不会改变
        int bitRate = 2000000; // 设置音频比特率,单位:b (比特率越高,清晰度/音质越好,当然文件也就越大 800000 = 800kb)
        int maxFrameRate = 20; // 视频帧率:15 f / s 帧率越低,效果越差
        int maxWidth = 1920;    //视频最大宽度(这里没使用)
        try {
            MultimediaObject object = new MultimediaObject(sourceFile);
            // 视频属性设置
            AudioInfo audioInfo = object.getInfo().getAudio();
            AudioAttributes audio = new AudioAttributes();
            // 设置通用编码格式
            audio.setCodec("aac");
            if (audioInfo.getBitRate() > maxBitRate) {
                audio.setBitRate(new Integer(maxBitRate));
            }
            audio.setChannels(audioInfo.getChannels());
            if (audioInfo.getSamplingRate() > maxSamplingRate) {
                audio.setSamplingRate(maxSamplingRate);
            }

            // 视频编码属性配置
            VideoInfo videoInfo = object.getInfo().getVideo();
            VideoAttributes video = new VideoAttributes();
            video.setCodec("h264");
            if (videoInfo.getBitRate() > bitRate) {
                video.setBitRate(bitRate);
            }
            if (videoInfo.getFrameRate() > maxFrameRate) {
                video.setFrameRate(maxFrameRate);
            }
            // 限制视频宽高: 不推荐设置; 如果视频宽度大于maxWidth值,则压缩后的视频宽度会拉宽变形(亲身经历);
            //int width = videoInfo.getSize().getWidth();
            //int height = videoInfo.getSize().getHeight();
            //if (width > maxWidth) {
            //    float rat = (float) width / maxWidth;
            //    video.setSize(new VideoSize(maxWidth, (int) (height / rat)));
            //}
            EncodingAttributes attr = new EncodingAttributes();
            attr.setFormat("mp4");
            attr.setAudioAttributes(audio);
            attr.setVideoAttributes(video);
            Encoder encoder = new Encoder();
            encoder.encode(new MultimediaObject(sourceFile), targetFile, attr);
            log.info("压缩后视频大小:[{}]",targetFile.length());
            String base64FromFile = getBase64FromFile(targetFile);

            //压缩后的base64转视频文件,可查看压缩后的视频:
            getFileFromBase64(base64FromFile,null);

            return base64FromFile;
        } catch (Exception e) {
            throw e;
        } finally {
            targetFile.delete();
        }
    }

    /**
     * 将文件转为base64
     */
    public static String getBase64FromFile(File file) throws IOException {
        FileInputStream in = null;
        ByteArrayOutputStream out = null;
        try {
            in = new FileInputStream(file);
            out = new ByteArrayOutputStream();
            int read = 0;
            byte[] buffer = new byte[1024];
            while ((read = in.read(buffer, 0, 1024)) != -1) {
                out.write(buffer, 0, read);
            }

            return Base64.getEncoder().encodeToString(out.toByteArray());
        } catch (IOException e) {
            throw e;
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null){
                out.close();
            }
        }
    }

    /**
     * 将MultipartFile转换为File
     */
    public static File MultipartFileToFile(MultipartFile multiFile) throws IOException {
        String fileName = multiFile.getOriginalFilename();
        String prefix = fileName.substring(fileName.lastIndexOf("."));
        InputStream in = null;
        OutputStream out = null;
        try {
            File file = File.createTempFile(fileName, prefix);
            out = new FileOutputStream(file);
            in = multiFile.getInputStream();
            int read = 0;
            byte[] buffer = new byte[1024];
            while ((read = in.read(buffer, 0, 1024)) != -1) {
                out.write(buffer, 0, read);
            }

            return file;
        } catch (Exception e) {
            throw e;
        }finally {
            if (in != null){
                in.close();
            }
            if (out != null){
                out.close();
            }
        }
    }

    /**
     * base64字符串转视频
     * @param base64Pic
     * @param filePath: 传空,则临时文件存放到项目更目录下;
     * @return
     * @throws Exception
     */
    public static File getFileFromBase64(String base64Pic,String filePath) throws Exception {
        File file = null;
        if (base64Pic != null) {
            try {
                filePath = Optional.ofNullable(filePath).orElse("");

                //文件目录
                if (!"".equals(filePath)) {
                    File fileMk = new File(filePath);
                    if (!fileMk.exists() && !fileMk.isDirectory()) {
                        fileMk.mkdirs();
                    }
                }

                BASE64Decoder decoder = new BASE64Decoder();
                //前台在用Ajax传base64值的时候会把base64中的+换成空格,所以需要替换回来。
                String baseValue = base64Pic.replaceAll(" ", "+");
                //去除base64中无用的部分
                byte[] b = decoder.decodeBuffer(baseValue.replace("data:video/mp4;base64,", ""));
                for (int i = 0; i < b.length; ++i) {
                    if (b[i] < 0) {
                        b[i] += 256;
                    }
                }

                //存到临时文件中
                file = new File(filePath + System.currentTimeMillis()+".mp4");
                OutputStream out = new FileOutputStream(file.getPath());
                out.write(b);
                out.flush();
                out.close();
            } catch (Exception e) {
                throw e;
            }finally {
                //删除filePath下的临时文件
                if (file != null) {
                    file.delete();
                }
            }
        }
        return file;
    }
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-01 15:33:33  更:2022-05-01 15:34:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:57:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码