[猴子学python] 2020-06-01 如保下载m3m(java版转python版)

欢迎使用CSDN-markdown编辑器123

引言

手头上有一个m3u8下载视频的java源码,但想转为python语言用来学习。我先看原java版的m3u8源码先撸了一遍,然后开发将他转了python版。

 

原java版

Main.java

package com.hhf.m3u8;

import java.io.File;
import java.io.IOException;

import static com.hhf.m3u8.Config.getConfig;
import static com.hhf.util.StringUtil.isMessyCode;

public class Main
{

    public static void main(String[] args) {
        String resource = getConfig("download.resource");
        String rootPath = getConfig("save.path");
        String ffmpeg=  getConfig("ffmpeg.path");
        if (isMessyCode(resource) || isMessyCode(rootPath)) {
            System.out.println("存在乱码");
            return;
        }
        String[] ss = resource.split(",");

        System.out.println();
        String fileName = ss[0];
        String m3u8Url = ss[1];
        M3U8Downloader downloader = new M3U8Downloader(ffmpeg, rootPath, fileName, m3u8Url);
        boolean isSuccess = downloader.start();
        try {
            if(isSuccess) {
                System.out.println("---------Compile MP4-------------");
                downloader.composeFile(downloader.getIndexFile());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("-------- DONE. ---------");
        System.exit(0);
    }
}

转换类(M3U8Downloader.java)

package com.hhf.m3u8;

import com.hhf.util.HttpsUtil;
import com.hhf.util.IOUtil;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class M3U8Downloader {
    String rootFile;
    String fileName;
    String m3u8Url;
    String ffmpeg;
    String indexFile;
    LinkedList<Download> downloadList = new LinkedList();
    LinkedList<Download> successList = new LinkedList();

    class Download {
        String url;
        File file;
        int downloadTime = 0;

        public Download(String url, File file) {
            this.url = url;
            this.file = file;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public File getFile() {
            return file;
        }

        public void setFile(File file) {
            this.file = file;
        }

        public int getDownloadTime() {
            return downloadTime;
        }

        public void setDownloadTime(int downloadTime) {
            this.downloadTime = downloadTime;
        }
    }

    class DownloadNet implements Runnable {

        @Override
        public void run() {

                while (!downloadList.isEmpty()) {
                    Download download;
                    synchronized (downloadList) {
                        if(downloadList.size()>0) {
                            download = downloadList.removeFirst();
                        }
                        else{
                            continue;
                        }
                        System.out.println("------> QUERY SIZE:" + downloadList.size() );
                    }

                    try {
                        if (download.file.exists()) {
                            System.out.println(download.file.getCanonicalPath() + " file exist, ignore download" );
                            continue;
                        }

                        System.out.println("Thread " + Thread.currentThread().getName() + " "  + Thread.currentThread().getId() + " " + download.getUrl());
                        File tmp = new File(download.file.getParent(), download.file.getName() + ".download");
                        boolean success = false;
                        InputStream inStream = null;
                        FileOutputStream fs = null;
                        try  {
                            inStream = new HttpsUtil().getInputStream(download.getUrl());
                            fs = new FileOutputStream(tmp);
                            int byteread = 0;
                            byte[] buffer = new byte[1204];
                            while ((byteread = inStream.read(buffer)) != -1) {
                                fs.write(buffer, 0, byteread);
                            }
                            success = true;
                        }
                        finally {
                            IOUtil.close(inStream);
                            IOUtil.close(fs);
                        }
                        if (success) {

                            if (tmp.renameTo(download.file)) {
                                synchronized (successList) {
                                    successList.add(download);
                                }
                                System.out.println(download.url + " success download to " + download.file.getCanonicalPath());
                            }
                        } else {
                            System.out.println(download.url + " download failure. ");
                        }
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    } catch (Exception e) {
                        e.printStackTrace();
                        if(download.downloadTime++<5){
                            synchronized (downloadList){
                                downloadList.add(download);
                            }
                        }
                    }
                }
            }
    }

    public M3U8Downloader(String ffmpeg, String rootFile, String fileName, String m3u8Url) {
        this.rootFile = rootFile;
        this.fileName = fileName;
        this.m3u8Url = m3u8Url;
        this.ffmpeg = ffmpeg;
        this.indexFile = (rootFile + File.separator  + fileName + File.separator + "index.m3u8").replaceAll("/", "\\\\");
    }

    public String getIndexFile(){
        return this.indexFile;
    }


    public String getUrlContent(String urlStr) throws Exception {
//        URL url = new URL(urlStr);
        HttpsUtil util = new HttpsUtil();
        return IOUtil.read(util.getInputStream(urlStr));
    }

    public boolean start() {
        try {
            File fileDir = new File(rootFile, fileName);
            if (!fileDir.exists()) {
                if (!fileDir.mkdirs()) {
                    throw new IOException("Create directory " + fileDir.getCanonicalPath() + " failure.");
                }
            }

            String indexName = getIndexName(m3u8Url);
            File indexFile = new File(fileDir, indexName);
            String content;
            if (!indexFile.exists()) {
                System.out.println("Not found index file " + indexFile.getCanonicalPath() + ",downloading.");
                content = getUrlContent(m3u8Url);
                if (saveFile(indexFile, content.getBytes())) {
                    System.out.println("Saved file:" + indexFile.getCanonicalPath());
                }
            } else {
                content = IOUtil.read(new FileInputStream(indexFile));
            }
            String baseUrl = getBaseUrl(m3u8Url);
            List<String> uri = analysisIndex(content);

           return download(baseUrl, fileDir, uri);
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
    }

    public String getBaseUrl(String url) {
        return url.substring(0, url.lastIndexOf("/") + 1);
    }

    public boolean saveFile(File file, byte[] data) {
        try (FileOutputStream fs = new FileOutputStream(file)) {
            fs.write(data);
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

    }

    public String getIndexName(String url) {
        int pos = url.lastIndexOf("/");
        return url.substring(pos + 1);
    }

    public boolean download(String baseUrl, File fileDir, List<String> ls) {
        int threadCount = 10;
        ExecutorService service = Executors.newFixedThreadPool(threadCount);
        for (String s : ls) {
            downloadList.add(new Download(baseUrl + s, new File(fileDir, s)));
        }
        for (int i = 0; i < threadCount; i++) {
            service.execute(new DownloadNet());
        }
        boolean isSuccess = true;
        try {
        service.shutdown();

        if (!service.awaitTermination(3600000, TimeUnit.SECONDS)) { //超时后直接关闭
            service.shutdownNow();
            isSuccess = true;
        }
        } catch (InterruptedException e) { //awaitTermination 出现中断异常也将触发关闭
            service.shutdownNow();
            isSuccess = false;
        }
        System.out.println("-------- download finish. ---------");
        return isSuccess;
    }


    public List analysisIndex(String content) throws Exception {
        Pattern pattern = Pattern.compile(".*ts");
        Matcher ma = pattern.matcher(content);

        List<String> list = new ArrayList<String>();

        while (ma.find()) {
            list.add(ma.group());
        }

        return list;
    }

    public String composeFile(String index2) throws IOException {
        String ffmpegCmds = (ffmpeg + " -allowed_extensions ALL -i " + index2 + " -c copy " + rootFile + File.separator + fileName + ".mp4").replaceAll("\\\\", "/").replaceAll("//", "/");
        System.out.println("CMD:" + ffmpegCmds);
        Process process = null;
        Runtime run = null;
        run = Runtime.getRuntime();

        long start = System.currentTimeMillis();
        try {
            Process p = run.exec(ffmpegCmds);
            //释放进程
            p.getOutputStream().close();
            p.getInputStream().close();
            p.getErrorStream().close();
            p.waitFor();
            long end = System.currentTimeMillis();
            System.out.println(ffmpegCmds + "  costs:" + (end - start) + "ms");
        } catch (Exception e) {
            System.out.println("--- FFmpeg命令执行出错! --- 出错信息: " + e.getMessage());
            return null;
        } finally {
            if (null != process) {
                process.destroy();
            }
        }

        return "--";
    }
}

Config.java

package com.hhf.m3u8;

import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;

public class Config
{
    private static Properties properties;
    public static String getConfig(String key){
        if(properties == null){
            properties  = new Properties();
            try(InputStreamReader bis = new InputStreamReader(Main.class.getResourceAsStream("/app.properties"), "UTF-8")) {
                properties.load(bis);
            }
            catch (IOException ex){
                throw  new RuntimeException("Not found the app.properties file.");
            }
        }
        String v = (String) properties.get(key);
        if(v == null){
            throw new RuntimeException("Not found the key:" + key);
        }
        return v;
    }
}

源码并不复杂,但我是java出身的我,如果转python呢?

 

参考

python3爬虫(3)下载流媒体m3u8
 - https://blog.csdn.net/liujiayu2/article/details/86083400

java转python代码 
 - https://blog.csdn.net/u011546806/article/details/45074557?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-2

python3 连接mysql
 - https://blog.csdn.net/wgz7747147820/article/details/91126868?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159099121519725222420004%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=159099121519725222420004&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-2-91126868.first_rank_ecpm_v2_pc_rank_v3&utm_term=python+mysql

 python与mysql(一)

https://blog.csdn.net/viafcccy/article/details/89289257?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159099121519725222420004%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=159099121519725222420004&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-3-89289257.first_rank_ecpm_v2_pc_rank_v3&utm_term=python+mysql

python 下载 M3U8 视频
 - https://blog.csdn.net/lswzw/article/details/100105646

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
好的,我可以给你讲一下猴子选大王问题的 Python 链表实现。 猴子选大王问题,也称为约瑟夫问题,是一个经典的数问题。问题的描述是:n 只猴子围成一圈,按顺序从 1 到 n 编号。从第 1 只猴子开始报数,报到 m 的猴子出圈,下一只猴子继续从 1 开始报数,直到最后只剩下一只猴子。那么这只猴子就是大王。 链表是一种常用的数据结构,可以用来解决这个问题。我们可以使用 Python 的链表实现来模拟这个过程。 首先,我们需要定义一个 Node 类来表示链表中的节点。节点应该包含两个属性:value 表示节点的值,next 表示指向下一个节点的指针。 ```python class Node: def __init__(self, value): self.value = value self.next = None ``` 接下来,我们可以定义一个链表类,其中包含两个属性:head 表示链表的头节点,tail 表示链表的尾节点。 ```python class LinkedList: def __init__(self): self.head = None self.tail = None ``` 对于链表的操作,我们可以定义一些方法。首先,我们可以定义一个 add_node 方法来向链表中添加节点。 ```python def add_node(self, value): new_node = Node(value) if self.head is None: self.head = new_node self.tail = new_node else: self.tail.next = new_node self.tail = new_node ``` 接下来,我们可以定义一个 remove_node 方法来从链表中删除节点。 ```python def remove_node(self, node): if node == self.head: self.head = node.next else: prev_node = self.head while prev_node.next != node: prev_node = prev_node.next prev_node.next = node.next if node == self.tail: self.tail = prev_node ``` 现在,我们可以使用链表来解决猴子选大王问题。首先,我们可以创建一个包含 n 只猴子的链表。 ```python n = 10 m = 3 monkeys = LinkedList() for i in range(1, n+1): monkeys.add_node(i) ``` 接下来,我们可以模拟猴子报数的过程。我们从头节点开始遍历链表,每次遍历到第 m 个节点时,就将该节点从链表中删除。我们重复这个过程,直到只剩下一只猴子为止。 ```python current_node = monkeys.head while monkeys.head != monkeys.tail: for i in range(m-1): current_node = current_node.next next_node = current_node.next monkeys.remove_node(current_node) current_node = next_node ``` 最后,我们可以输出最后剩下的猴子的编号,即大王的编号。 ```python print(monkeys.head.value) # 输出大王的编号 ``` 这就是猴子选大王问题的 Python 链表实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值