From 43ece45336445cd58ab895312ed211044d8af5c8 Mon Sep 17 00:00:00 2001 From: lwl0608 Date: Sat, 13 Jul 2024 12:58:57 +0800 Subject: [PATCH] x --- cronjob/media/vd_compress.py | 186 ++++++++++++++++++++++++++++------- media/calc_media.py | 25 +++++ 2 files changed, 177 insertions(+), 34 deletions(-) create mode 100644 media/calc_media.py diff --git a/cronjob/media/vd_compress.py b/cronjob/media/vd_compress.py index eb07152..32b655a 100644 --- a/cronjob/media/vd_compress.py +++ b/cronjob/media/vd_compress.py @@ -4,8 +4,9 @@ from lib.all import * import ffmpy import cv2 import oss2 +import subprocess -service_name = 'vd_compress' +service_name = 'vd_compress_new' # log_dir = '/app/log' log_dir = '/Users/erwin/data/log' logger = Logger(service_name, log_dir=log_dir) @@ -26,23 +27,72 @@ endpoint_internal = "https://oss-cn-hangzhou.aliyuncs.com" bucket_name = "wishpal-ironfan-media" -def get_video_w_h(path): +class VdHelper: + def __init__(self, vd_path): + self._video = cv2.VideoCapture(vd_path) + + self._vd_path = vd_path + self._width = int(self._video.get(cv2.CAP_PROP_FRAME_WIDTH)) + self._height = int(self._video.get(cv2.CAP_PROP_FRAME_HEIGHT)) + self._fps = int(self._video.get(cv2.CAP_PROP_FPS)) + + print(f"w: {self._width}, h: {self._height}, fps: {self._fps}") + + def get_vd_path(self): + return self._vd_path + + def get_fps(self): + return self._fps + + def get_w_h(self): + return self._width, self._height + + def remove(self): + return os.remove(self._vd_path) + + def resize(self, p=1080): + if self._width > self._height: + rate = float(p) / float(self._height) + new_width = int(float(self._width) * rate) + new_height = p + else: + rate = float(p) / float(self._width) + new_width = p + new_height = int(float(self._height) * rate) + + return new_width, new_height + + def transfer_h264_720p_25fps(self, output_path): + new_width, new_height = self.resize(720) + new_size_str = "{}x{}".format(new_width, new_height) + output_args = '-c:v libx264 -s {} -crf {}'.format(new_size_str, 23) + if self.get_fps() > 25: + output_args = '-c:v libx264 -s {} -crf {} -r 25'.format(new_size_str, 23) + ff = ffmpy.FFmpeg( + inputs={self.get_vd_path(): None}, + outputs={output_path: output_args} + ) + ff.run() + + +def get_video_w_h(path, p=1080): video = cv2.VideoCapture(path) width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH)) height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)) + fps = int(video.get(cv2.CAP_PROP_FPS)) # 横屏 960 * 540 if width > height: - rate = float(720) / float(height) + rate = float(p) / float(height) new_width = int(float(width) * rate) - new_height = 720 + new_height = p else: - rate = float(720) / float(width) - new_width = 720 + rate = float(p) / float(width) + new_width = p new_height = int(float(height) * rate) - return width, height, new_width, new_height + return width, height, new_width, new_height, fps # video_path = "bbbbb.mov" @@ -64,7 +114,7 @@ class S: def get_one_wait_compress_video(self): param = { - "ids": [52062], + "ids": [], # 52062 "status": 0, "offset": 0, "limit": 1, @@ -76,12 +126,14 @@ class S: return lis[0] return None - def set_compress_finish(self, video_id, size_src, src_id_h264, size_h264, status, resize_t): + def set_compress_finish(self, video_id, size_src, src_id_h264, size_h264, src_id_720, size_720, status, resize_t): param = { "id": video_id, "size_src": size_src, "src_id_h264": src_id_h264, "size_h264": size_h264, + "src_id_720": src_id_720, + "size_720": size_720, "status": status, "resize_t": resize_t, } @@ -90,60 +142,81 @@ class S: ret = safe_get_int(res, "ret") return ret - def proc_one(self): - video = self.get_one_wait_compress_video() - if not video: - return - + def proc_one(self, video): video_id = safe_get_int(video, "id") src_id = safe_get_str(video, "src_id") - src_id_h264 = src_id.replace("vdprod", "vdprodh264") + src_id_h264_720 = src_id.replace("vdprod", "vdprodh264720") + src_id_python_type = src_id.replace("/", "_") - src_id_h264_python_type = src_id_h264.replace("/", "_") + src_id_h264_720_python_type = src_id_h264_720.replace("/", "_") cur_dir = os.getcwd() + "/" local_src_path = cur_dir + src_id_python_type - local_h264_path = cur_dir + src_id_h264_python_type + local_h264_720_path = cur_dir + src_id_h264_720_python_type # 下载视频到本地 obj = self.save_video_from_oss(src_id, local_src_path) content_type = safe_get_str(obj.headers, "Content-Type") file_size = int(safe_get_str(obj.headers, "Content-Length")) - local_src_path_new = local_src_path if content_type == "video/mp4": local_src_path_new = local_src_path + ".mp4" elif content_type == "video/quicktime": local_src_path_new = local_src_path + ".mov" + elif content_type == "video/x-m4v": + local_src_path_new = local_src_path + ".m4v" else: - logger.Info("invalid content_type, id: {}, src_id: {}, content_type: {}", video_id, self.hw_cdn_host + src_id, content_type) - return + logger.Error("invalid content_type, id: {}, src_id: {}, content_type: {}".format(video_id, self.hw_cdn_host + src_id, content_type)) + return False os.renames(local_src_path, local_src_path_new) - # 转成264 mp4 - input_file = local_src_path_new - output_file = local_h264_path + ".mp4" - ff = ffmpy.FFmpeg( - inputs={input_file: None}, - outputs={output_file: '-c:v libx264'} - ) - ff.run() + # vd helper + vdh = VdHelper(local_src_path_new) + # 转成264 720p mp4 + output_file = local_h264_720_path + ".mp4" + vdh.transfer_h264_720p_25fps(output_file) # 上传 - upload_ret = self.upload_video_to_oss(output_file, src_id_h264) + upload_ret = self.upload_video_to_oss(output_file, src_id_h264_720) upload_ret_status = upload_ret.status logger.Info("upload_ret, {}, {}".format(src_id, upload_ret_status)) output_content_type = "video/mp4" output_file_size = os.path.getsize(output_file) # 更新db - db_ret = self.set_compress_finish(video_id, file_size, src_id_h264, output_file_size, 100, int(time.time())) + db_ret = self.set_compress_finish(video_id, file_size, "", 0, src_id_h264_720, output_file_size, 100, int(time.time())) - os.remove(input_file) + vdh.remove() os.remove(output_file) logger.Info("before, {}, {}, {}".format(src_id, content_type, file_size)) - logger.Info("after_h264, {}, {}, {}, {}".format(src_id_h264, output_content_type, output_file_size, db_ret)) - logger.Info("host: {}".format(self.hw_cdn_host + src_id_h264)) + logger.Info("after_h264720, {}, {}, {}, {}".format(src_id_h264_720, output_content_type, output_file_size, db_ret)) + logger.Info("host: {}".format(self.hw_cdn_host + src_id_h264_720)) + return True + + +def proc_test_h264(input_file, output_file): + # 转成264 mp4 + ff = ffmpy.FFmpeg( + inputs={input_file: None}, + outputs={output_file: '-c:v libx264'} + ) + ff.run() + + +def proc_test_h264_720(input_file, output_file, crf): + vdh = VdHelper(input_file) + + # 转成264 mp4 + new_width, new_height = vdh.resize(720) + new_size_str = "{}x{}".format(new_width, new_height) + output_args = '-c:v libx264 -s {} -crf {}'.format(new_size_str, crf) + if vdh.get_fps() > 25: + output_args = '-c:v libx264 -s {} -crf {} -r 25'.format(new_size_str, crf) + ff = ffmpy.FFmpeg( + inputs={input_file: None}, + outputs={output_file: output_args} + ) + ff.run() def get_video_stat(video_path): @@ -166,8 +239,53 @@ def get_video_stat(video_path): print(f"高度: {height}") +def get_bit_rate(video_path): + import subprocess + + # 使用ffmpeg命令获取视频码率信息 + command = ["ffmpeg", "-i", video_path, "-hide_banner", "-loglevel", "error"] + output = subprocess.check_output(command, stderr=subprocess.STDOUT) + + # 解析ffmpeg输出中的码率信息 + for line in output.decode().split('\n'): + if 'bitrate' in line: + print(line) + + +# 示例用法 +# bitrate = get_video_bitrate("xvd1_src.mov") +# +# if bitrate: +# print(f"视频码率: {bitrate} kbps") + s = S() +# s.proc_one() +idx = 0 while True: - s.proc_one() + video = s.get_one_wait_compress_video() + if not video: + logger.Info("no video, sleep") + time.sleep(10) + continue + idx += 1 + video_id = safe_get_int(video, "id") + try: + logger.Info("================== {}, {} start ==================".format(idx, video_id)) + ok = s.proc_one(video) + if not ok: + s.set_compress_finish(video_id, 0, "", 0, "", 0, -100, int(time.time())) + logger.Info("================== {}, {} end ==================".format(idx, video_id)) + except Exception as e: + logger.Error("{}, {} _Panic: {}".format(idx, video_id, str(e))) + s.set_compress_finish(video_id, 0, "", 0, "", 0, -100, int(time.time())) # get_video_stat("vdprod_7b_09_f8c4-bd63-4d4a-898b-6d1431f06994.mov") # get_video_stat("vdprod_7b_09_f8c4-bd63-4d4a-898b-6d1431f06994.mp4") + +# get_video_stat("big_src.mov") +# # proc_test_h264("big_src.mov", "big_h264_1080.mp4") +# proc_test_h264_720("big_src.mov", "big_h264_720_0.mp4", 0) +# proc_test_h264_720("big_src.mov", "big_h264_720_23.mp4", 23) +# proc_test_h264_720("big_src.mov", "big_h264_720_30.mp4", 30) +# proc_test_h264_720("big_src.mov", "big_h264_720_40.mp4", 40) +# proc_test_h264_720("big_src.mov", "big_h264_720_50.mp4", 50) +# # get_bit_rate("xvd1_h264_720.mp4") diff --git a/media/calc_media.py b/media/calc_media.py new file mode 100644 index 0000000..b4981f8 --- /dev/null +++ b/media/calc_media.py @@ -0,0 +1,25 @@ +from lib.all import * + + +class S: + def __init__(self): + self.col_video = MongoDB( + host="mongodb://root:Wishpal2024@dds-bp1da1ddd62bede41.mongodb.rds.aliyuncs.com:3717,dds-bp1da1ddd62bede42.mongodb.rds.aliyuncs.com:3717/admin?replicaSet=mgset-77304659", + port=3717, + db="media", + collection="video" + ) + print(self.col_video) + + def __del__(self): + self.col_video.close() + + def proc(self): + q = {} + docs = self.col_video.find(q) + df = pd.DataFrame(docs) + df.to_csv("media.csv") + + +s = S() +s.proc()