去掉m3u8的片头和片尾

Posted littlehb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了去掉m3u8的片头和片尾相关的知识,希望对你有一定的参考价值。

# pip3 install -i https://mirrors.aliyun.com/pypi/simple/ m3u8
# pip3 install -i https://mirrors.aliyun.com/pypi/simple/ oss2
# pip3 install --upgrade pip

# 在Centos中安装ffmpeg和aria2c
# https://www.cnblogs.com/littlehb/p/9347978.html

import m3u8, sys
import os, subprocess
import oss2, requests, datetime

# ========================================================================
# 前面需要截取的时间长度,单位:秒
prefixCutSeconds = 10
# 后面需要截取的时间长度,单位:秒
suffixCutSeconds = 5
# 上传的路径前缀
prefix = down/M3u8_ZhengZhou103/

# ========================================================================
# 访问oss的用户名与密码,无需修改
access_key_id = xxxxxxxxxxxx
access_key_secret = xxxxxxxxxxxx
bucket_name = dsideal-yy


# 检查是内网还是外网
def CheckInOut():
    # 探测内网外网
    print(正在探测使用环境是阿里云内网还是外网,请稍等...)
    url = http:// + bucket_name + .oss-cn-qingdao-internal.aliyuncs.com/down/Material/42/42385DBE-E03F-FF6A-A37C-CC8A04612BE4.doc
    try:
        requests.get(url, timeout=1)
        endpoint = http://oss-cn-qingdao-internal.aliyuncs.com/
        print(内部网络访问,将使用endpoint: + endpoint)
    except Exception as err:
        endpoint = http://oss-cn-qingdao.aliyuncs.com/
        print(外网访问,将使用endpoint: + endpoint)
    return endpoint


# 从哪个结点下进行操作
endpoint = CheckInOut()

# 从哪里下载回来,如果是内网,应该写成 http://dsideal_yy.oss-cn-qingdao-internal.aliyuncs.com
if internal in endpoint:
    downloadPrefixUrl = http:// + bucket_name + .oss-cn-qingdao-internal.aliyuncs.com/down/M3u8/
else:
    downloadPrefixUrl = http:// + bucket_name + .oss-cn-qingdao.aliyuncs.com/down/M3u8/


# 获取视频的时间长度
def GetVideoLength(fileName):
    cmd = "ffmpeg -i " + fileName + " 2>&1 | grep ‘Duration‘ | cut -d ‘ ‘ -f 4 | sed s/,//"
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
    out, err = p.communicate()
    for line in out.splitlines():
        return (line.decode()[0:8])


# 将时间换算成秒数
def t2s(t):
    h, m, s = t.strip().split(":")
    return int(h) * 3600 + int(m) * 60 + int(s)


# 下载m3u8的所有ts文件
def DoActionM3u8(m3u8_url):
    # m3u8文件的真实名称
    m3u8FileName = WorkingPath + "/" + m3u8_url.split(/)[-1]
    print(M3u8真实文件名称: + m3u8FileName)
    # 构造两个文本文件
    m3u8List = []
    m3u8FileList = []
    m3u8_obj = m3u8.load(m3u8_url)
    for l in m3u8_obj.segments:
        m3u8List.append(downloadPrefixUrl + l.uri[0:2] + / + l.uri)
        m3u8FileList.append("file ‘" + l.uri + "")

    # 形成文本文件,这个用于调用aria2c进行批量下载使用
    tempFile = WorkingPath + /url.txt
    result = map(lambda x: x.strip() + 
, m3u8List)
    with open(tempFile, w) as f:
        f.writelines(result)

    # 下载回来转码后的视频ts
    cmd = aria2c -c -s 4 -d  + WorkingPath +  -j 8 -i  + tempFile
    os.system(cmd)

    # 形成文本文件,用于将ts文件拼接成大的ts文件时使用
    tempFile = WorkingPath + /mylist.txt
    result = map(lambda x: x.strip() + 
, m3u8FileList)
    with open(tempFile, w) as f:
        f.writelines(result)

    # 使用ffmpeg 拼成大的ts
    tempAllTs = WorkingPath + /output.ts
    if os.path.exists(tempAllTs):
        os.remove(tempAllTs)

    tempAllTs_new = WorkingPath + /output_new.ts
    if os.path.exists(tempAllTs_new):
        os.remove(tempAllTs_new)

    tempAllMp4 = WorkingPath + /output.mp4
    if os.path.exists(tempAllMp4):
        os.remove(tempAllMp4)

    tempAllMp4_new = WorkingPath + /output_new.mp4
    if os.path.exists(tempAllMp4_new):
        os.remove(tempAllMp4_new)

    # 拼接为原始的ts
    cmd = ffmpeg -f concat -i  + tempFile +  -c copy  + tempAllTs +  -y
    os.system(cmd)
    #
    # 将大的ts转为mp4
    cmd = ffmpeg -i  + tempAllTs +  -c:v copy -c:a copy -bsf:a aac_adtstoasc  + tempAllMp4
    os.system(cmd)
    os.remove(tempAllTs)
    # 以下为new的步骤=========================================================================
    #
    #  截取一部分
    # (1) 测出文件有多长
    videoLength = GetVideoLength(tempAllMp4)
    # 去掉后suffixCutSeconds秒
    seconds = t2s(videoLength) - suffixCutSeconds
    m, s = divmod(seconds, 60)
    h, m = divmod(m, 60)
    endTime = "%02d:%02d:%02d" % (h, m, s)

    # 开始的秒数
    m, s = divmod(prefixCutSeconds, 60)
    h, m = divmod(m, 60)
    startTime = "%02d:%02d:%02d" % (h, m, s)
    # #
    # # (2)去头部prefixCutSeconds秒,尾部suffixCutSeconds秒
    print(截取并生成mp4!)
    cmd = ffmpeg  -i  + tempAllMp4 +  -vcodec copy -acodec copy -ss  + startTime +  -to  + endTime +   + tempAllMp4_new +  -y
    os.system(cmd)
    os.remove(tempAllMp4)
    print(生成新mp4成功!到这里都是非常正常的!!!!!)

    # (3) mp4 转 ts
    cmd = ffmpeg -y -i  + tempAllMp4_new +  -vcodec copy -acodec copy -vbsf h264_mp4toannexb  + tempAllTs_new
    os.system(cmd)
    os.remove(tempAllMp4_new)

    # (4) 切割ts
    prefixName = m3u8_url.split(/)[-1][0:36]
    cmd = ffmpeg -i  + tempAllTs_new +  -c copy -map 0 -f segment -segment_list  + WorkingPath + / + prefixName + .m3u8 -segment_time 10  + WorkingPath + / + prefixName + %03d.ts
    os.system(cmd)
    os.remove(tempAllTs_new)

    # (5)上传到oss,放到另一个目录下
    path = os.listdir(os.getcwd()+/M3u8)
    for filename in path:
        if os.path.isfile(WorkingPath+/+filename):
            if .m3u8 in filename or .ts in filename:
                logInfo(开始进行文件上传: + filename)
                key = prefix +  filename[0:2] + / + filename
                bucket.put_object_from_file(key, WorkingPath + / + filename, progress_callback=percentage)
                print(文件上传云存储成功完成! + filename)


# 黄海定义的输出信息的办法,带当前时间
def logInfo(msg):
    i = datetime.datetime.now()
    print(" %s            %s" % (i, msg))


# 进度条功能
def percentage(consumed_bytes, total_bytes):
    if total_bytes:
        per = int(100 * (float(consumed_bytes)) / (float(total_bytes)))
        s1 = "
[%s%s]%d%%" % ("=" * int(per), " " * (100 - int(per)), per)
        sys.stdout.write(s1)
        sys.stdout.flush()


if __name__ == __main__:
    # 删除临时目录并重新创建
    WorkingPath = /usr/local/software/TestM3u8/M3u8
    os.system(rm -rf  + WorkingPath)
    os.mkdir(WorkingPath)

    # 构建OSS存储对象
    auth = oss2.Auth(access_key_id, access_key_secret)
    # 阿里云上应该用这个内部网络选项
    bucket = oss2.Bucket(auth, endpoint, bucket_name)

    # 以一个名师云课为例
    m3u8_url = downloadPrefixUrl+C4/C4CD770E-C98A-AF8C-8B53-8541210B355B.m3u8
    print(m3u8_url)
    DoActionM3u8(m3u8_url)
# http://video.edusoa.com/down/M3u8_ZhengZhou103/C4/C4CD770E-C98A-AF8C-8B53-8541210B355B.m3u8
# http://dsideal-yy.oss-cn-qingdao.aliyuncs.com/down/M3u8_ZhengZhou103/C4/C4CD770E-C98A-AF8C-8B53-8541210B355B.m3u8
#

 

以上是关于去掉m3u8的片头和片尾的主要内容,如果未能解决你的问题,请参考以下文章

视频二次裁剪时间计算出原片的时间片段算法

谁有关于百变小樱的片尾曲歌词(中文)

幻影忍者海盗季片头曲叫啥?

《百变小樱》动画版中片尾曲叫啥名字? 就是那个“滴答,友情无时不甜美,就像水果那样新鲜”

从SQLServer里面取出数据,去掉头尾的空格

电视剧母版制作规范