Пример #1
0
 def hls(self, fixed: bool = False, encrypt: bool = False) -> str:
     """
     生成m3u8格式的文件
     :param fixed: 严格限制ts的时常
     :param encrypt: 是否加密
     :return: m3u8文件的所在的目录
     """
     fix_time = vargs.HLSTimeFixed.FIXED.value if fixed else vargs.HLSTimeFixed.NOFIXED.value
     encrypt_opts = utils_video._get_hls_enc_option() if encrypt else ''
     uuid_str = str(uuid.uuid1())
     output_dir = f'/tmp/{uuid_str}/ts'
     self.tmpfiles = output_dir
     ts_prefix = uuid_str
     outpath = f'/tmp/{uuid_str}/{uuid_str}.m3u8'
     # if not utils_common._run_ffmpeg_cmd(f'mkdir -pv {output_dir}'):
     #     return None
     try:
         cmd = ffcmd.CMD_HLS_VIDEO.format(inpath=self.filename,
                                          outpath=outpath,
                                          encrypt_opts=encrypt_opts,
                                          fix_time=fix_time,
                                          output_dir=output_dir,
                                          ts_prefix=ts_prefix)
         # print(cmd)
         if utils_common._run_ffmpeg_cmd(cmd):
             if utils_common._run_ffmpeg_cmd(
                     f"sed -i s@/tmp/{uuid_str}/@@g {outpath}"):
                 self.tmpfiles.remove(output_dir)
                 return output_dir
     except ValueError:
         pass
Пример #2
0
 def gif(self, start: float, last: float, height: int) -> str:
     """
     视频截图,从开始时间截取一帧作为图片
     :param start: 开始时间
     :param last: 持续时间,单位秒
     :param height: 图片高度(宽度等比缩放)
     :return: 成功: 图片路径 | 失败: None
     """
     try:
         if 0 < last <= self.duration and 0 <= start < self.duration - last \
                 and 0 < height <= vargs.VIDEO_HEIGHT:
             passlog_prefix = f"{tempfile.mktemp(dir='/tmp')}.png"
             self.tmpfiles = passlog_prefix  # 加入临时文件集合,以便集中处理
             outpath = f"{tempfile.mktemp(dir='/tmp')}.gif"  # gif 输出文件
             self.tmpfiles = outpath  # 加入临时文件集合,以便集中处理
             cmd = ffcmd.CMD_CREATEGIF.format(inpath=self.filename,
                                              outpath=outpath,
                                              start=start,
                                              last=last,
                                              height=height,
                                              passlog_prefix=passlog_prefix)
             if utils_common._run_ffmpeg_cmd(cmd):
                 self.tmpfiles.remove(outpath)
                 return outpath
     except ValueError:
         pass
Пример #3
0
def _init_video2mp4(inpath: str, outpath: str) -> bool:
    """
    将视频容器格式转化为mp4,并去除旋转元数据,统一视频流的index == 0, 音频流的index == 1
    并且会去掉字幕流
    :param inpath: 视频输入文件
    :param outpath: 视频输出文件
    :return: 成功: True| 失败: False
    """
    return _run_ffmpeg_cmd(
        ffcmd.CMD_CH_VIDEO_META.format(inpath=inpath, outpath=outpath))
Пример #4
0
 def move(self, newpath) -> bool:
     """
     将self.filename移动到newpath这个路径
     newpath 不能是目录, newpath必须以.mp4结尾
     :param newpath: self.filename 的新路径
     :return: 成功: True | 失败: False
     """
     newpath = os.path.abspath(newpath)
     if os.path.isdir(newpath):  # 新路径是目录
         return False
     if not newpath.endswith('.mp4'):  # 新路径不是.mp4结尾
         return False
     dir_path, file_path = os.path.split(newpath)
     if not utils_common._run_ffmpeg_cmd(
             f"mkdir -pv '{dir_path}'"):  # 创建新路径的目录
         return False
     if not utils_common._run_ffmpeg_cmd(
             f"mv -f '{self.filename}' '{newpath}'"):  # 移动文件
         return False
     self.filename = newpath
     return True
Пример #5
0
def _run_cutvideo_cmd(inpath: str, outpath: str, start: float,
                      last: float) -> bool:
    """
    将视频从start处开始,裁剪到start+last处
    :param inpath: 输入文件路径
    :param outpath: 输出文件路径
    :param start: 开始时间
    :param last: 持续时间
    :return: 命令执行成功: True | 失败: False
    """
    cmd = ffcmd.CMD_CUTVIDEO.format(inpath=inpath,
                                    outpath=outpath,
                                    start=start,
                                    last=last)
    # print(cmd)
    return _run_ffmpeg_cmd(cmd)
Пример #6
0
 def __add__(self, other: 'X264Codec'):
     """
     用于视频拼接
     """
     cls = self.__class__
     if not isinstance(other, cls):
         raise ValueError(f'{other} is not a instance of {cls.__name__}.')
     concat_file = f"{tempfile.mktemp(dir='/tmp')}.txt"
     self.tmpfiles = concat_file
     concat_file_contend = f"file '{self.filename}'\nfile '{other.filename}'\n"
     utils_common._write_file(concat_file, concat_file_contend)
     outpath = f"{tempfile.mktemp(dir='/tmp')}.mp4"  # 拼接后视频文件
     self.tmpfiles = outpath  # 加入临时文件集合,以便集中处理
     cmd = ffcmd.CMD_CONCAT_VIDEO_SAFE.format(concat_file=concat_file,
                                              outpath=outpath)
     if utils_common._run_ffmpeg_cmd(cmd):
         self.tmpfiles.remove(outpath)
         return self.__class__.from_format_video(outpath)
     else:
         raise OSError('can not add this two X264Video.')
Пример #7
0
 def snapshot(self, start: float, height: int) -> str:
     """
     视频截图,从开始时间截取一帧作为图片
     :param start: 开始时间
     :param height: 图片高度(宽度等比缩放)
     :return: 成功: 图片路径 | 失败: None
     """
     try:
         if 0 <= start < self.duration and 0 < height <= vargs.VIDEO_HEIGHT:
             outpath = f"{tempfile.mktemp(dir='/tmp')}.jpg"  # 截图输出文件
             self.tmpfiles = outpath  # 加入临时文件集合,以便集中处理
             cmd = ffcmd.CMD_SNAPSHOT.format(inpath=self.filename,
                                             outpath=outpath,
                                             start=start,
                                             height=height)
             if utils_common._run_ffmpeg_cmd(cmd):
                 self.tmpfiles.remove(outpath)
                 return outpath
     except ValueError:
         pass
Пример #8
0
def _run_video2h264_cmd(inpath: str, inimgs: str, outpath: str,
                        filter_opts: str, vbitrate: int) -> bool:
    """
    执行 ffcmd.CMD_VIDEO2H264 命令
    :param inpath: 输入文件路径
    :param inimgs: 输入图片路参数
    :param outpath: 输出文件路径
    :param filter_opts: 过滤器参数
    :param vbitrate: 视频码率
    :return: 命令执行成功: True | 失败: False
    """
    passlog_prefix = f'/tmp/ffmpeg2passlog.{time.time()}.{os.path.split(tempfile.mktemp())[1]}'
    cmd = ffcmd.CMD_VIDEO2H264.format(
        inpath=inpath,
        inimgs=inimgs,
        outpath=outpath,
        passlog_prefix=passlog_prefix,
        filter_opts=filter_opts,
        vbitrate=vbitrate,
    )
    # print(cmd)
    ret = _run_ffmpeg_cmd(cmd)  # 执行 ffmpeg 命令
    _run_cmd(f'rm -rf {passlog_prefix}*')  # 删除pass日志
    return ret