java 将bilibili m4s转为MP4,使用FFmpeg

FFmpeg 最好到先下载好
FFmpeg官网

经过测试 大概1G左右分段视频 大概所需要 1s左右,但是比较吃IO,所以最好 输出目录最好到 固态硬盘哈。

使用maven的依赖

  		<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.30<</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.16</version>
        </dependency>
         <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.6</version>
        </dependency>			
package com.xiaoyun.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class BiliMerge {


    public static void main(String[] args) throws IOException {
        //bilibili视频缓存所在的文件夹,自动递归查找文件夹
        String inFile = "F:\\xiaoyun6";
        //ffmpeg.exe 的所在目录
        String ffmpegFile = ("D:\\log\\ffmpeg\\bin\\ffmpeg.exe");
        //输出目录
        String outFile = "F:\\xiaoyun6\\movie\\";

        long start = System.currentTimeMillis();
        runffmpeg(inFile, outFile, ffmpegFile);
        System.out.println("所用时间:" + (System.currentTimeMillis() - start));

    }

    public static void runffmpeg(String inFile, String outFile, String ffmpegFile) {
        fileName(new File(inFile));
        list.stream().parallel()
                .filter(biliName -> !new File(new StringBuilder(outFile).append(biliName.getName()).append(".mp4").toString()).isFile())
                .forEach(biliName ->
                        {
                            if (StringUtils.isNotEmpty(biliName.getAudioFile()) && StringUtils.isNotEmpty(biliName.getVideoFile())) {
                                ffmpegUtil(biliName.getVideoFile(), biliName.getAudioFile(), new StringBuilder(outFile).append(biliName.getName()).append(".mp4").toString(),
                                        ffmpegFile);
                                System.out.println(biliName.getName() + ",转换成功");
                            } else {
                                if (null == biliName.getVideoFile()) {
                                    System.err.println("编号id为:" + biliName.getId() + " 输入的video.m4s 不存在" + ".详细信息为: " + biliName);
                                }
                                if (null == biliName.getAudioFile()) {
                                    System.err.println("编号id为:" + biliName.getId() + " 输入的audio.m4s 不存在" + ".详细信息为: " + biliName);
                                }
                            }
                        }
                );


    }

    private static List<BiliName> list = new ArrayList<>();

    public static void fileName(File file) {
        if (file.isDirectory()) {
            String[] directoryList = file.list();
            if (ArrayUtils.isNotEmpty(directoryList)) {
                for (String directory : directoryList) {
                    fileName(new File(file, directory));
                }
            }
        }
        String fileName = file.getName();
        if (file.isFile()) {
            if ("entry.json".equals(fileName)) {
                String id = file.getParentFile().getName();
                readerName(id, file);
            }
            if ("audio.m4s".equals(fileName) || "video.m4s".equals(fileName)) {
                File parentFile = parentName(file);
                Integer avId = Integer.valueOf(parentFile.getParentFile().getName());
                BiliName biliName = findBiliById(parentFile.getName(), avId);
                if ("audio.m4s".equals(fileName)) {
                    biliName.setAudioFile(file.getPath());
                }
                if ("video.m4s".equals(fileName)) {
                    biliName.setVideoFile(file.getPath());
                }
            }
        }
    }

    private static BiliName findBiliById(String id, Integer avId) {
        if (list != null) {
            for (BiliName biliName : list) {
                if (biliName != null && id.equals(biliName.getId()) && avId.equals(biliName.getAvid())) {
                    return biliName;
                }
            }
        }
        BiliName biliName = new BiliName();
        biliName.setId(id);
        biliName.setAvid(avId);
        list.add(biliName);
        return biliName;
    }


    private static File parentName(File file) {
        return file.getParentFile().getParentFile();
    }

    private static void setName(String id, Integer avid, String parentName, String name) {
        if (list != null) {
            for (BiliName biliName : list) {
                if (biliName != null && id.equals(biliName.getId()) && avid.equals(biliName.getAvid())) {
                    biliName.setParentName(parentName);
                    biliName.setName(name);
                    biliName.setAvid(avid);
                    break;
                }
            }
        }
    }

    private static void readerName(String id, File file) {
        BufferedReader bufferedReader = null;
        FileInputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        try {
            inputStream = new FileInputStream(file);
            inputStreamReader = new InputStreamReader(inputStream);
            bufferedReader = new BufferedReader(inputStreamReader);
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line);
            }
            String jsonStr = sb.toString();
            Map map = JSON.parseObject(jsonStr, Map.class);
            if (map.containsKey("title") && map.containsKey("avid")) {
                String title = (String) map.get("title");
                Integer avid = (Integer) map.get("avid");
                if (map.containsKey("page_data")) {
                    JSONObject page_data = (JSONObject) map.get("page_data");
                    String download_subtitle = (String) page_data.get("download_subtitle");
                    setName(id, avid, title, download_subtitle);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    private static void ffmpegUtil(String videoFile, String audioFile, String outFile, String FFmpeg) {
        if (videoFile == null || audioFile == null || outFile == null || FFmpeg == null) {
            return;
        } else {
            ProcessBuilder processBuilder = new ProcessBuilder();
            List<String> command = new ArrayList<>();
            command.add(FFmpeg);
            command.add("-i");
            command.add(videoFile);
            command.add("-i");
            command.add(audioFile);
            command.add("-codec");
            command.add("copy");
            command.add(outFile);
            processBuilder.command(command);
            processBuilder.redirectErrorStream(true);

//            InputStream inputStream = null;
            Process process = null;
            try {
                //启动进程
                process = processBuilder.start();
//                inputStream = process.getInputStream();
                //转成字符流
//                List list = IOUtils.readLines(inputStream, "utf-8");
//                list.stream().forEach(System.out::println);
            } catch (IOException e) {
                e.printStackTrace();
//            } finally {
//                IOUtils.closeQuietly(inputStream);
            }
        }
    }
}

@Data
class BiliName {
    private String id;
    private String parentName;
    private String name;
    private String videoFile;
    private String audioFile;
    private Integer avid;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值