• 根据M3U8地址下载视频


           下面展示的是通过M3U8地址,把这个地址转为一个视频文件;只是一个基本案例,当然,有些下载的M3U8文件里面格式是不一样的,还有的是加过密的,道理都是一个道理。

    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.URL;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import org.apache.commons.io.IOUtils;
     
    /**
     * 根据M3U8地址下载视频
     * IOUtils.copyLarge 需要引入commons.io包
     * 
     * java.version 1.7
     */
    public class M3U8Downloader {
     
        /** m3u8地址 */
        private static String url = "http://playertest.longtailvideo.com/adaptive/bipbop/gear4/prog_index.m3u8";
        /** 正式文件存储地址(合并之后的文件) */
        private static String tofile = "E:\m3u8\Movie.ts";
        /** 临时文件存储地址(M3U8视频段) */
        private static String tofileTemp = "E:\m3u8\temp";
         
        private static ExecutorService executor = Executors.newFixedThreadPool(10);
     
        public static void main(String[] args) throws IOException, InterruptedException {
            //解析M3U8地址为对象
            M3U8 m3u8 = parseIndex(url);
     
            //根据M3U8对象获取时长
            float duration = getDuration(m3u8);
            System.out.println("时长: " + ((int) duration / 60) + "分" + (int) duration % 60 + "秒");
             
            //根据M3U8对象下载视频段
            download(m3u8, tofileTemp);
     
            //关闭线程池
            executor.shutdown();
            System.out.println("等待下载中...");
            while (!executor.isTerminated()) {
                Thread.sleep(100);
            }
     
            //合并文件
            merge(m3u8, tofile, tofileTemp);
             
            System.out.println("下载完成,合并的文件在: " + tofile);
        }
         
        /**
         * 根据M3U8对象获取时长
         * @param m3u8
         * @return
         */
        private static float getDuration(M3U8 m3u8){
            float duration = 0;
            for (M3U8Ts ts : m3u8.getTsList()) {
                duration += ts.getSeconds();
            }
            return duration;
        }
     
        /**
         * 合并文件
         * @param m3u8
         * @param tofile
         * @throws IOException
         */
        public static void merge(M3U8 m3u8, String tofile, String tofileTemp) throws IOException {
            File file = new File(tofile);
            FileOutputStream fos = new FileOutputStream(file);
             
            File fileTempDir = new File(tofileTemp);
            for (File fileTemp : fileTempDir.listFiles()) {
                IOUtils.copyLarge(new FileInputStream(fileTemp), fos);
            }
             
            fos.close();
        }
         
        /**
         * 根据M3U8对象下载视频段
         * @param m3u8
         * @param tofile
         * @throws IOException
         */
        public static void download(final M3U8 m3u8, final String tofileTemp) throws IOException {
            final File dir = new File(tofileTemp);
            if (!dir.exists()) {
                dir.mkdirs();
            }
     
            for (final M3U8Ts ts : m3u8.getTsList()) {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            FileOutputStream writer = new FileOutputStream(new File(dir, ts.getFile()));
                            IOUtils.copyLarge(new URL(m3u8.getBasepath() + ts.getFile()).openStream(), writer);
                            writer.close();
                            System.out.println("视频段: " + ts + "下载完成");
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }
     
        /**
         * 解析M3U8地址为对象
         * @param url M3U8地址
         */
        static M3U8 parseIndex(String url) throws IOException {
     
            BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(url).openStream()));
     
            String basepath = url.substring(0, url.lastIndexOf("/") + 1);
     
            M3U8 ret = new M3U8();
            ret.setBasepath(basepath);
     
            String line;
            float seconds = 0;
            while ((line = reader.readLine()) != null) {
                if (line.startsWith("#")) {
                    if (line.startsWith("#EXTINF:")) {
                        line = line.substring(8);
                        if (line.endsWith(",")) {
                            line = line.substring(0, line.length() - 1);
                        }
                        if (line.contains(",")) {
                            line = line.substring(0, line.indexOf(","));
                        }
                        seconds = Float.parseFloat(line);
                    }
                    continue;
                }
                if (line.endsWith("m3u8")) {
                    return parseIndex(basepath + line);
                }
                ret.addTs(new M3U8Ts(line, seconds));
                seconds = 0;
            }
            reader.close();
     
            return ret;
        }
     
        static class M3U8 {
            private String basepath;
            private List<M3U8Ts> tsList = new ArrayList<M3U8Ts>();
     
            public String getBasepath() {
                return basepath;
            }
     
            public void setBasepath(String basepath) {
                this.basepath = basepath;
            }
     
            public List<M3U8Ts> getTsList() {
                return tsList;
            }
     
            public void setTsList(List<M3U8Ts> tsList) {
                this.tsList = tsList;
            }
     
            public void addTs(M3U8Ts ts) {
                this.tsList.add(ts);
            }
     
            @Override
            public String toString() {
                StringBuilder sb = new StringBuilder();
                sb.append("basepath: " + basepath);
                for (M3U8Ts ts : tsList) {
                    sb.append("
    ts: " + ts);
                }
     
                return sb.toString();
            }
     
        }
     
        static class M3U8Ts {
            private String file;
            private float seconds;
     
            public M3U8Ts(String file, float seconds) {
                this.file = file;
                this.seconds = seconds;
            }
     
            public String getFile() {
                return file;
            }
     
            public void setFile(String file) {
                this.file = file;
            }
     
            public float getSeconds() {
                return seconds;
            }
     
            public void setSeconds(float seconds) {
                this.seconds = seconds;
            }
     
            @Override
            public String toString() {
                return file + " (" + seconds + "sec)";
            }
        }
    }
  • 相关阅读:
    vim:spell语法
    ubuntu安装texlive2019
    virtualbox安装ubuntu
    正在阅读的tex教程
    Koa 框架介绍以及 Koa2.x 环境搭建
    检测Android应用的通知栏权限开启状态(已经适配8.0以上系统)
    Redis 的 8 大应用场景
    Redis问与答
    SpringBoot中使用Redis
    Mac环境下安装Redis
  • 原文地址:https://www.cnblogs.com/kawhileonardfans/p/10966838.html
Copyright © 2020-2023  润新知