Java后端利用ffmpeg做视频转码(通过视频访问链接直接进行)

一、下载ffmpeg

下载地址:http://www.ffmpeg.org/download.html。下载完成后,解压到自己喜欢的目录。

二、命令行转码(参考https://blog.csdn.net/guojianwei2011/article/details/83242789)

进入上一步解软件目录的bin目录下,输入以下命令即可,

ffmpeg -i “https://xxx/xxx/xxx.m3u8” -vcodec copy -acodec copy -absf aac_adtstoasc /xxx/xxx/xxx.mp4

其中 http://xxx/xxx/xxx.m3u8 视频的m3u8地址, /xxx/xxx/xxx.mp4 为输出mp4的文件目录及文件名

三、Java程序解码(代码仅供参考)

/**
 * hilbert.xu 2019-03-01
 */
public class ConvertVideo {
    private static final String projectDir = new ApplicationHome(ConvertVideo.class).getDir().toString();

    /**
     * 视频转化
     *
     * @param url        视频源地址
     * @param ffmpegPath ffmpeg 软件安装目录
     * @return
     */
    public static Map convertVideo(String url, String ffmpegPath) {
        Map map = new HashMap<>();
        String toolPath = ffmpegPath;
        if (StringUtils.isBlank(toolPath)) {
            toolPath = getFfmpegPath();
        }
        String outputPath = getOutputPath();
        map.put("path", outputPath);
        map.put("flag", false);
        try {
            Boolean ffmpeg = FfmpegUtil.ffmpeg(toolPath, url, outputPath);
            map.put("flag", ffmpeg);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 获取ffmpeg执行文件的路径
     *
     * @return
     */
    private static String getFfmpegPath() {
        return projectDir + File.separator + "ffmpeg";
    }

    /**
     * 获取输出文件名
     *
     * @return
     */
    private static String getOutputPath() {
        String tempPath = projectDir + File.separator + "video" + File.separator;
        File tempFolder = new File(tempPath);
        if (!tempFolder.exists()) {
            boolean mkdirs = tempFolder.mkdirs();
            if (mkdirs) {
                return tempPath + UUID.randomUUID().toString().replaceAll("-", "") + ".mp4";
            }
        }
        return tempPath + UUID.randomUUID().toString().replaceAll("-", "") + ".mp4";
    }
}
/**
 * 根据视频地址转换m3u8格式为mp4
 * 

* hilbert.xu 2019-03-01 */ public class FfmpegUtil { /** * 将视频转换为ts流 * * @param ffmpegPath ffmpegPath bin路径 * @param url 源文件路径 * @param outputPath 输出文件路径 * @return */ public static Boolean ffmpeg(String ffmpegPath, String url, String outputPath) throws Exception { List command = getFfmpegCommand(ffmpegPath, url, outputPath); if (null != command && command.size() > 0) { return process(command); } return false; } /** * @param command * @throws Exception */ private static boolean process(List command) { try { if (null == command || command.size() == 0) { return false; } Process videoProcess = new ProcessBuilder(command).redirectErrorStream(true).start(); new PrintStream(videoProcess.getErrorStream()).start(); new PrintStream(videoProcess.getInputStream()).start(); int exitcode = videoProcess.waitFor(); if (exitcode == 1) { return false; } return true; } catch (Exception e) { e.printStackTrace(); } return false; } /** * 根据文件类型设置ffmpeg命令 * * @param url * @param outputPath * @return */ private static List getFfmpegCommand(String ffmpegPath, String url, String outputPath) { List command = new ArrayList<>(); command.add(ffmpegPath + File.separator + "ffmpeg"); command.add("-i"); command.add(url); command.add("-vcodec"); command.add("copy"); command.add("-acodec"); command.add("copy"); command.add("-absf"); command.add("aac_adtstoasc"); command.add(outputPath); return command; } } class PrintStream extends Thread { java.io.InputStream __is = null; public PrintStream(java.io.InputStream is) { __is = is; } public void run() { try { while (this != null) { int _ch = __is.read(); if (_ch == -1) { break; } else { System.out.print((char) _ch); } } } catch (Exception e) { e.printStackTrace(); } } }

三、总结

本位只提供一种转码形式,如有其他需要可以参看ffmpeg文档进行功能扩充。具体执行命令可以参考getFfmpegCommand方法进行封装。

希望大家可以参考本文,根据自己的业务需求进行扩充。有何疑问欢迎大家一起讨论。

把技术死磕到底。

你可能感兴趣的:(Java,技术集成,Shell脚本)