瀏覽代碼

视频封面灵活支持功能

zhangyong 1 年之前
父節點
當前提交
e9cbfc3627
共有 3 個文件被更改,包括 162 次插入69 次删除
  1. 2 2
      agc_bk_main.py
  2. 12 3
      common/material.py
  3. 148 64
      video_agc/agc_video_method.py

+ 2 - 2
agc_bk_main.py

@@ -42,8 +42,8 @@ def video_task():
     # 创建一个线程池
     with concurrent.futures.ThreadPoolExecutor() as executor:
         futures = {executor.submit(video_start, user_data): user_data for user_data in data}
-        # 设置超时时间为20分钟
-        timeout = 25 * 60
+        # 设置超时时间为360分钟
+        timeout = 360 * 60
         # 等待所有任务执行完成或超时
         for future in concurrent.futures.as_completed(futures, timeout=timeout):
             try:

+ 12 - 3
common/material.py

@@ -224,7 +224,11 @@ class Material():
             uid = row[1]
             text = row[2]
             video = row[0]
-            number = {"uid": uid, "text": text}
+            if len(row) == 3:
+                cover = ''
+            else:
+                cover = 1
+            number = {"uid": uid, "text": text, "cover": cover}
             if uid:
                 list.append(number)
             if video:
@@ -233,9 +237,10 @@ class Material():
             list1 = random.choice(list)
             uid1 = list1['uid']
             srt = list1['text']
+            cover = list1['cover']
             id_list = cls.get_uid(uid1, mark)
             if len(id_list) < 2:
-                return uid1, srt, video_list
+                return uid1, srt, video_list, cover
 
     # 获取音频类型+字幕+标题
     @classmethod
@@ -255,7 +260,11 @@ class Material():
             uid = row[0]
             text = row[1]
             video = row[2]
-            number = {"uid": uid, "text": text, "video": video}
+            if len(row) == 3:
+                cover = ''
+            else:
+                cover = 1
+            number = {"uid": uid, "text": text, "video": video, cover: "cover"}
             if uid:
                 list_data.append(number)
             else:

+ 148 - 64
video_agc/agc_video_method.py

@@ -7,6 +7,7 @@ import subprocess
 import sys
 import time
 import urllib.parse
+import json
 
 import requests
 from datetime import datetime, timedelta
@@ -186,24 +187,77 @@ class AgcVidoe():
         # 使用 FFmpeg 将 SRT 转换为 ASS
         subprocess.run(["ffmpeg", "-i", s_path, a_path])
 
+
+    @classmethod
+    def get_cover(cls, uid):
+        time.sleep(1)
+        url = "https://admin.piaoquantv.com/manager/video/multiCover/listV2"
+
+        payload = json.dumps({
+            "videoId": uid,
+            "range": "2h"
+        })
+        headers = {
+            'accept': 'application/json',
+            'accept-language': 'zh-CN,zh;q=0.9',
+            'cache-control': 'no-cache',
+            'content-type': 'application/json',
+            'cookie': 'SESSION=YjU3MzgwNTMtM2QyYi00YjljLWI3YWUtZTBjNWYwMGQzYWNl',
+            'origin': 'https://admin.piaoquantv.com',
+            'pragma': 'no-cache',
+            'priority': 'u=1, i',
+            'sec-ch-ua': '"Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99"',
+            'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36'
+        }
+
+        response = requests.request("POST", url, headers=headers, data=payload)
+        data = response.json()
+        content = data["content"]
+        if len(content) == 1:
+            return content[0]["coverUrl"]
+        max_share_count = 0
+        selected_cover_url = ""
+        for item in content:
+            share_count = item.get("shareWeight")
+            if share_count is not None and share_count > max_share_count:
+                max_share_count = share_count
+                selected_cover_url = item["coverUrl"]
+            elif share_count == max_share_count and item["createUser"] == "用户":
+                selected_cover_url = item["coverUrl"]
+        return selected_cover_url
+
+
     # 新生成视频上传到对应账号下
     @classmethod
-    def insert_piaoquantv(cls, oss_object_key, audio_title, pq_ids_list):
+    def insert_piaoquantv(cls, oss_object_key, audio_title, pq_ids_list, cover, uid):
         for i in range(2):
-
             url = "https://vlogapi.piaoquantv.com/longvideoapi/crawler/video/send"
-            payload = dict(pageSource='vlog-pages/post/post-video-post', videoPath=oss_object_key, width='720',
-                           height='1280', fileExtensions='mp4', viewStatus='1', title=audio_title,
-                           careModelStatus='1',
-                           token='f04f58d6e664cbc9902660a1e8d20ce6cd7fdb0f', loginUid=pq_ids_list[i],
-                           versionCode='719',
-                           machineCode='weixin_openid_o0w175aZ4FJtqVsA1tcozJDJHdDU', appId='wx89e7eb06478361d7',
-                           clientTimestamp='1703337579331',
-                           machineInfo='{"sdkVersion":"3.2.5","brand":"iPhone","language":"zh_CN","model":"iPhone 12 Pro<iPhone13,3>","platform":"ios","system":"iOS 15.6.1","weChatVersion":"8.0.44","screenHeight":844,"screenWidth":390,"pixelRatio":3,"windowHeight":762,"windowWidth":390,"softVersion":"4.1.719"}',
-                           sessionId='1703337560040-27bfe208-a389-f476-db1d-840681e04b32',
-                           subSessionId='1703337569952-8f56d53c-b36d-760e-8abe-0b4a027cd5bd', senceType='1089',
-                           hotSenceType='1089', id='1050', channel='pq')
-
+            if cover:
+                payload = dict(pageSource='vlog-pages/post/post-video-post', videoPath=oss_object_key, width='720',
+                               height='1280', fileExtensions='mp4', viewStatus='1', title=audio_title,
+                               careModelStatus='1',
+                               token='f04f58d6e664cbc9902660a1e8d20ce6cd7fdb0f', loginUid=pq_ids_list[i],
+                               versionCode='719',
+                               machineCode='weixin_openid_o0w175aZ4FJtqVsA1tcozJDJHdDU', appId='wx89e7eb06478361d7',
+                               clientTimestamp='1703337579331',
+                               machineInfo='{"sdkVersion":"3.2.5","brand":"iPhone","language":"zh_CN","model":"iPhone 12 Pro<iPhone13,3>","platform":"ios","system":"iOS 15.6.1","weChatVersion":"8.0.44","screenHeight":844,"screenWidth":390,"pixelRatio":3,"windowHeight":762,"windowWidth":390,"softVersion":"4.1.719"}',
+                               sessionId='1703337560040-27bfe208-a389-f476-db1d-840681e04b32',
+                               subSessionId='1703337569952-8f56d53c-b36d-760e-8abe-0b4a027cd5bd', senceType='1089',
+                               hotSenceType='1089', id='1050', channel='pq')
+            else:
+                cover = cls.get_cover(uid)
+                payload = dict(pageSource='vlog-pages/post/post-video-post', videoPath=oss_object_key, width='720',
+                               height='1280', fileExtensions='mp4', viewStatus='1', title=audio_title,
+                               coverImgPath=cover,
+                               careModelStatus='1',
+                               token='f04f58d6e664cbc9902660a1e8d20ce6cd7fdb0f', loginUid=pq_ids_list[i],
+                               versionCode='719',
+                               machineCode='weixin_openid_o0w175aZ4FJtqVsA1tcozJDJHdDU', appId='wx89e7eb06478361d7',
+                               clientTimestamp='1703337579331',
+                               machineInfo='{"sdkVersion":"3.2.5","brand":"iPhone","language":"zh_CN","model":"iPhone 12 Pro<iPhone13,3>","platform":"ios","system":"iOS 15.6.1","weChatVersion":"8.0.44","screenHeight":844,"screenWidth":390,"pixelRatio":3,"windowHeight":762,"windowWidth":390,"softVersion":"4.1.719"}',
+                               sessionId='1703337560040-27bfe208-a389-f476-db1d-840681e04b32',
+                               subSessionId='1703337569952-8f56d53c-b36d-760e-8abe-0b4a027cd5bd', senceType='1089',
+                               hotSenceType='1089', id='1050', channel='pq')
             payload['videoPath'] = oss_object_key
             payload['title'] = audio_title
             data = urllib.parse.urlencode(payload)
@@ -388,50 +442,81 @@ class AgcVidoe():
             subtitle_cmd =  "drawtext=text='分享、转发给群友':x=(w-text_w)/2:y=h-text_h-15:fontsize=28:fontcolor=black:fontfile=/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc"
         # 背景色参数
         background_cmd = "drawbox=y=ih-65:color=yellow@1.0:width=iw:height=0:t=fill"
-        VIDEO_COUNTER = 0
-        FF_INPUT = ""
-        FF_SCALE = ""
-        FF_FILTER = ""
-        ffmpeg_cmd = ["ffmpeg"]
-        for videos in video_files:
-            Common.logger("video").info(f"{mark}的{platform}视频:{videos[3]}")
-            # 添加输入文件
-            FF_INPUT += f" -i {videos[3]}"
-            # 为每个视频文件统一长宽,并设置SAR(采样宽高比)
-            FF_SCALE += f"[{VIDEO_COUNTER}:v]scale=320x480,setsar=1[v{VIDEO_COUNTER}];"
-            # 为每个视频文件创建一个输入流,并添加到-filter_complex参数中
-            FF_FILTER += f"[v{VIDEO_COUNTER}][{VIDEO_COUNTER}:a]"
-            # 增加视频计数器
-            VIDEO_COUNTER += 1
-        # 构建最终的FFmpeg命令
-        ffmpeg_cmd.extend(FF_INPUT.split())
-        ffmpeg_cmd.extend(["-filter_complex", f"{FF_SCALE}{FF_FILTER}concat=n={VIDEO_COUNTER}:v=1:a=1[v][a]",
-                           "-map", "[v]", "-map", "[a]", v_path])
-
-        # 多线程数
-        num_threads = 4
-        # 构建 FFmpeg 命令,生成视频
-        ffmpeg_cmd_oss = [
-            "ffmpeg",
-            "-i", v_path,  # 视频文件列表
-            "-i", audio_video,  # 音频文件
-            "-c:v", "libx264",  # 复制视频流
-            "-c:a", "aac",  # 编码音频流为AAC
-            "-threads", str(num_threads),
-            "-vf", f"{background_cmd},{subtitle_cmd}",  # 添加背景色和字幕
-            "-t", str(int(audio_duration)),  # 保持与音频时长一致
-            "-map", "0:v:0",  # 映射第一个输入的视频流
-            "-map", "1:a:0",  # 映射第二个输入的音频流
-            "-y",  # 覆盖输出文件
-            v_oss_path
-        ]
-        try:
-            subprocess.run(ffmpeg_cmd)
-            if os.path.isfile(v_path):
+        if platform == "koubo" or platform == "zhannei":
+            text_ptah = cls.bk_text_folders(mark)
+            with open(text_ptah, 'w') as f:
+                for file in video_files:
+                    f.write(f"file '{file[3]}'\n")
+            # 多线程数
+            num_threads = 4
+            ffmpeg_cmd_oss = [
+                "ffmpeg",
+                "-f", "concat",
+                "-safe", "0",
+                "-i", f"{text_ptah}",  # 视频文件列表
+                "-i", audio_video,  # 音频文件
+                "-c:v", "libx264",
+                "-c:a", "aac",
+                "-threads", str(num_threads),
+                "-vf", f"scale=320x480,{background_cmd},{subtitle_cmd}",  # 添加背景色和字幕
+                "-t", str(int(audio_duration)),  # 保持与音频时长一致
+                "-map", "0:v:0",  # 映射第一个输入的视频流
+                "-map", "1:a:0",  # 映射第二个输入的音频流
+                "-y",  # 覆盖输出文件
+                v_oss_path
+            ]
+            try:
                 subprocess.run(ffmpeg_cmd_oss)
-            print("视频处理完成!")
-        except subprocess.CalledProcessError as e:
-            print(f"视频处理失败:{e}")
+                print("视频处理完成!")
+                if os.path.isfile(text_ptah):
+                    os.remove(text_ptah)
+            except subprocess.CalledProcessError as e:
+                print(f"视频处理失败:{e}")
+        else:
+            VIDEO_COUNTER = 0
+            FF_INPUT = ""
+            FF_SCALE = ""
+            FF_FILTER = ""
+            ffmpeg_cmd = ["ffmpeg"]
+            for videos in video_files:
+                Common.logger("video").info(f"{mark}的{platform}视频:{videos[3]}")
+                # 添加输入文件
+                FF_INPUT += f" -i {videos[3]}"
+                # 为每个视频文件统一长宽,并设置SAR(采样宽高比)
+                FF_SCALE += f"[{VIDEO_COUNTER}:v]scale=320x480,setsar=1[v{VIDEO_COUNTER}];"
+                # 为每个视频文件创建一个输入流,并添加到-filter_complex参数中
+                FF_FILTER += f"[v{VIDEO_COUNTER}][{VIDEO_COUNTER}:a]"
+                # 增加视频计数器
+                VIDEO_COUNTER += 1
+            # 构建最终的FFmpeg命令
+            ffmpeg_cmd.extend(FF_INPUT.split())
+            ffmpeg_cmd.extend(["-filter_complex", f"{FF_SCALE}{FF_FILTER}concat=n={VIDEO_COUNTER}:v=1:a=1[v][a]",
+                               "-map", "[v]", "-map", "[a]", v_path])
+
+            # 多线程数
+            num_threads = 4
+            # 构建 FFmpeg 命令,生成视频
+            ffmpeg_cmd_oss = [
+                "ffmpeg",
+                "-i", v_path,  # 视频文件列表
+                "-i", audio_video,  # 音频文件
+                "-c:v", "libx264",  # 复制视频流
+                "-c:a", "aac",  # 编码音频流为AAC
+                "-threads", str(num_threads),
+                "-vf", f"{background_cmd},{subtitle_cmd}",  # 添加背景色和字幕
+                "-t", str(int(audio_duration)),  # 保持与音频时长一致
+                "-map", "0:v:0",  # 映射第一个输入的视频流
+                "-map", "1:a:0",  # 映射第二个输入的音频流
+                "-y",  # 覆盖输出文件
+                v_oss_path
+            ]
+            try:
+                subprocess.run(ffmpeg_cmd)
+                if os.path.isfile(v_path):
+                    subprocess.run(ffmpeg_cmd_oss)
+                print("视频处理完成!")
+            except subprocess.CalledProcessError as e:
+                print(f"视频处理失败:{e}")
         print(f"{mark}的{platform}:视频拼接成功啦~~~")
         Common.logger("video").info(f"{mark}的{platform}:视频拼接成功啦~~~")
         return video_files
@@ -459,8 +544,6 @@ class AgcVidoe():
             yhmw_count = 0
         else:
             yhmw_count = int(int(yhmw_all_count)/2)
-
-
         # 如果没有该文件目录则创建,有文件目录的话 则删除文件
         s_path, v_path, video_path_url, v_oss_path = cls.create_folders(mark)
 
@@ -481,7 +564,7 @@ class AgcVidoe():
                         Feishu.bot('recommend', 'AGC完成通知', '今日常规自制视频拼接任务完成啦~', mark, mark_name)
                         return mark
                 # 获取音频类型+字幕+标题
-                uid, srt, video_list = Material.get_all_data(feishu_id, link, mark)
+                uid, srt, video_list, cover_status = Material.get_all_data(feishu_id, link, mark)
                 # 获取已入库的用户id
                 user_id = cls.get_user_id(platform, mark)
                 # 获取 未使用的视频链接
@@ -534,7 +617,7 @@ class AgcVidoe():
                     cls.insert_videoAudio(video_files, uid, platform, mark)
                     Common.logger("video").info(f"{mark}的{platform}渠道完成已使用视频存入数据库")
                     Common.logger("video").info(f"{mark}的{platform}渠道开始视频添加到对应用户")
-                    piaoquantv = cls.insert_piaoquantv(oss_object_key, audio_title, pq_ids_list)
+                    piaoquantv = cls.insert_piaoquantv(oss_object_key, audio_title, pq_ids_list, cover_status, uid)
                     if piaoquantv:
                         Common.logger("video").info(f"{mark}的{platform}渠道视频添加到对应用户成功")
                     if os.path.isfile(v_oss_path):
@@ -576,7 +659,7 @@ class AgcVidoe():
         #     Feishu.bot('recommend', 'AGC完成通知', '今日脚本跟随视频拼接任务完成啦~', mark.split("-")[0], mark_name)
         #     return mark
         # 获取音频类型+字幕+标题
-        uid, srt, video_list = Material.get_all_data(feishu_id, link, mark)
+        uid, srt, video_list, cover = Material.get_all_data(feishu_id, link, mark)
         platform_list = ex_list["platform_list"] # 渠道
         # 如果没有该文件目录则创建,有文件目录的话 则删除文件
         s_path, v_path, video_path_url, v_oss_path = cls.create_folders(mark)
@@ -651,7 +734,7 @@ class AgcVidoe():
                 cls.insert_videoAudio(video_files, uid, platform, mark)
                 Common.logger("gs_video").info(f"{mark}的{platform}渠道完成已使用视频存入数据库")
                 Common.logger("gs_video").info(f"{mark}的{platform}渠道开始视频添加到对应用户")
-                piaoquantv = cls.insert_piaoquantv(oss_object_key, audio_title, pq_ids_list)
+                piaoquantv = cls.insert_piaoquantv(oss_object_key, audio_title, pq_ids_list, cover, uid)
                 if piaoquantv:
                     Common.logger("gs_video").info(f"{mark}的{platform}渠道视频添加到对应用户成功")
                 if os.path.isfile(v_oss_path):
@@ -690,6 +773,7 @@ class AgcVidoe():
                 uid = data['uid']  # 音频id
                 srt = data['text']  # srt
                 videos = data['video']
+                cover = data['cover']
                 if ',' in videos:
                     videos = videos.split(',')
                 else:
@@ -735,7 +819,7 @@ class AgcVidoe():
                         Common.logger("bk_video").info(f"{mark}拼接视频发送成功,OSS 地址:{oss_object_key}")
                         time.sleep(10)
                         Common.logger("bk_video").info(f"{mark}开始视频添加到对应用户")
-                        piaoquantv = cls.insert_piaoquantv(oss_object_key, audio_title, pq_ids_list)
+                        piaoquantv = cls.insert_piaoquantv(oss_object_key, audio_title, pq_ids_list, cover, uid)
                         if piaoquantv:
                             Common.logger("bk_video").info(f"{mark}视频添加到对应用户成功")
                         if os.path.isfile(v_oss_path):