Browse Source

增加ai片尾

zhangyong 11 months ago
parent
commit
fe47c5372e
3 changed files with 194 additions and 125 deletions
  1. 77 18
      common/gpt4o_help.py
  2. 94 96
      common/tts_help.py
  3. 23 11
      video_rewriting/video_prep.py

+ 77 - 18
common/gpt4o_help.py

@@ -18,29 +18,30 @@ class GPT4o():
     
                     第一:根据下面的优秀标题示例,总结优秀标题特点,生成一个新标题。
                     此视频献给四零后,看完感触颇多!
-                    🔴88岁三胞胎兄妹表演《沙家浜》,开口惊艳全场!
-                    50年前毛主席就告诫了,今天一一验证!苦的还是老百姓
-                    🔴十分通透的一段话,写得太棒了,请朋友们收好!
-                    🏆那个部位最先知道脑梗呢
-                    ✿这才叫老同学聚会,到了这个年纪,还能聚在一起真不容易
-                    活久未见的照片,历史书上看不到,了解那些鲜为人知的过去
-                    🚩中国人正在丢失的这几样东西!都转发看看吧~
-                    🔥热热热!三伏天到了应该注意什么?一起看看❗
+                    示例case:
+                        🔴88岁三胞胎兄妹表演《沙家浜》,开口惊艳全场!
+                        50年前毛主席就告诫了,今天一一验证!苦的还是老百姓
+                        🔴十分通透的一段话,写得太棒了,请朋友们收好!
+                        🏆那个部位最先知道脑梗呢
+                        ✿这才叫老同学聚会,到了这个年纪,还能聚在一起真不容易
+                        活久未见的照片,历史书上看不到,了解那些鲜为人知的过去
+                        🚩中国人正在丢失的这几样东西!都转发看看吧~
+                        🔥热热热!三伏天到了应该注意什么?一起看看❗
     
                     第二:生成过程有如下的规范、约束和建议:
                     1.标题开头包含醒目emoji🔴,整体字符长度控制在10-20;
                     2.不能包含#话题和@人;
                     3.不能编造:不能加入原标题没有的实体信息,如原标题没有养老金,不能在生成的标题中出现养老金;
                     4.不能使用无实质信息和强烈诱导点击、紧急、夸张、震惊的描述:在提高标题吸引力的同时,严格落实不使用“必看”、“错过悔恨终生”类描述,错误危险标题示例:
-                    万万想不到真的太好了看了3遍,你也快看看吧!
-                    🌸绝对不能错过,快打开看看,越快越好
-                    所有老年人一定要看
-                    天大的好消息,5月开始实施❗
-                    就在刚刚,中国突然传出重磅消息,所有人都不敢相信!🚩
-                    丧尽天良!为什么生病的人越来越多,原来吃的是这些🎈
-                    今年的端午节太特殊,一辈子难遇一次!一定要看!错过别后悔
-                    好消息来了,千万别划走!
-                    紧急!已爆发,错过就晚了😱
+                        万万想不到真的太好了看了3遍,你也快看看吧!
+                        🌸绝对不能错过,快打开看看,越快越好
+                        所有老年人一定要看
+                        天大的好消息,5月开始实施❗
+                        就在刚刚,中国突然传出重磅消息,所有人都不敢相信!🚩
+                        丧尽天良!为什么生病的人越来越多,原来吃的是这些🎈
+                        今年的端午节太特殊,一辈子难遇一次!一定要看!错过别后悔
+                        好消息来了,千万别划走!
+                        紧急!已爆发,错过就晚了😱
     
                     输出格式:要求输出格式为符合RFC8259标准的JSON格式的字符串,不要以代码块形式返回,返回一个string类型的新标题。
                     '''
@@ -85,7 +86,65 @@ class GPT4o():
                 if attempt == max_retries - 1:
                     return "🔴好漂亮的视频,给你最美的祝福❗"
 
+    @classmethod
+    def get_ai_pw(cls, title):
+        max_retries = 3
+        for attempt in range(max_retries):
+
+            content = '''
+                        请针对微信平台视频类小程序场景,面向人群是中国中老年人,在单聊、群聊场景,对不同类型的内容,生成结尾引导分享的脚本。引导用户发生更多的分享行为。要求优化过程综合考虑下面的要求:  
+                        第一.根据下面的示例case,总结分享引导脚本特点,生成分享引导脚本  
+                        示例case1: 
+                         标题:此视频献给四零后,看完感触颇多!
+                         分享引导脚本: 
+                         说的太好了 ,忍不住分享给了您 ,字字在理 ,句句入心 ,赶紧把视频转发出去 ,和老友们一起分享 ,转发的越多 ,收获的福气就越多!
+                        
+                        第二:生成过程有如下的规范、约束和建议: 
+                        1.不能编造:不能加入原标题没有的实体信息,如原标题没有养老金,不能在生成的标题中出现养老金;  
+                        2.不能使用强烈的诱导、夸张词汇:在提高分享吸引力的同时,严格落实不使用“必做”、“错过悔恨终生”类描述; 
+                        3.分享引导总长控制在5-10句话,每句话字符长度控制在4-10字; 
+                        4.分享引导脚本保持自然的语言风格  
+                        输出格式:要求输出格式为符合RFC8259标准的JSON格式的字符串,不要以代码块形式返回,返回一个string类型的分享引导脚本。
+                        '''
+
+            url = "http://aigc.piaoquantv.com/aigc-server/aigc/conversation"
+            headers = {
+                "Content-Type": "application/json"
+            }
+            payload = {
+                "auth": "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",
+                "openAiGptParam": {
+                    "model": "gpt-4o",
+                    "temperature": 0.5,
+                    "messages": [
+                        {
+                            "role": "system",
+                            "content": content
+                        },
+                        {
+                            "role": "user",
+                            "content": title
+                        }
+                    ]
+                }
+            }
+            wait_time = random.uniform(5, 20)
+            time.sleep(wait_time)
+            response = requests.post(url, headers=headers, json=payload)
+            response = response.json()
+            try:
+                match = re.search(r'"[^"]+": "([^"]+)"', str(response))
+                if match:
+                    pw = match.group(1)
+                    return pw
+                else:
+                    if attempt == max_retries - 1:
+                        return None
+            except Exception:
+                if attempt == max_retries - 1:
+                    return None
+
 
 if __name__ == '__main__':
-    title = '二胎营养师、育婴师双证宝妈告诉你!怀孕真正不能吃的是这些!看一遍你是记不住的,收藏下来吧!孕期禁忌怀孕孕妈怀孕不能吃什么怀孕那些事'
+    title = '请叫我kitty女王看到kitty请疯狂砸向我!k门永存hellokitty可爱到犯规购物分享'
     GPT4o.get_ai_title(title)

+ 94 - 96
common/tts_help.py

@@ -1,97 +1,95 @@
-# -*- coding: UTF-8 -*-
-# Python 2.x引入httplib模块。
-# import httplib
-# Python 3.x引入http.client模块。
-import http.client
-# Python 2.x引入urllib模块。
-# import urllib
-# Python 3.x引入urllib.parse模块。
-import urllib.parse
+import subprocess
+
+import requests
 import json
-def processGETRequest(appKey, token, text, audioSaveFile, format, sampleRate) :
-    host = 'nls-gateway-cn-shanghai.aliyuncs.com'
-    url = 'https://' + host + '/stream/v1/tts'
-    # 设置URL请求参数
-    url = url + '?appkey=' + appKey
-    url = url + '&token=' + token
-    url = url + '&text=' + text
-    url = url + '&format=' + format
-    url = url + '&sample_rate=' + str(sampleRate)
-    # voice 发音人,可选,默认是xiaoyun。
-    # url = url + '&voice=' + 'xiaoyun'
-    # volume 音量,范围是0~100,可选,默认50。
-    # url = url + '&volume=' + str(50)
-    # speech_rate 语速,范围是-500~500,可选,默认是0。
-    # url = url + '&speech_rate=' + str(0)
-    # pitch_rate 语调,范围是-500~500,可选,默认是0。
-    # url = url + '&pitch_rate=' + str(0)
-    print(url)
-    # Python 2.x请使用httplib。
-    # conn = httplib.HTTPSConnection(host)
-    # Python 3.x请使用http.client。
-    conn = http.client.HTTPSConnection(host)
-    conn.request(method='GET', url=url)
-    # 处理服务端返回的响应。
-    response = conn.getresponse()
-    print('Response status and response reason:')
-    print(response.status ,response.reason)
-    contentType = response.getheader('Content-Type')
-    print(contentType)
-    body = response.read()
-    if 'audio/mpeg' == contentType :
-        with open(audioSaveFile, mode='wb') as f:
-            f.write(body)
-        print('The GET request succeed!')
-    else :
-        print('The GET request failed: ' + str(body))
-    conn.close()
-def processPOSTRequest(appKey, token, text, audioSaveFile, format, sampleRate) :
-    host = 'nls-gateway-cn-shanghai.aliyuncs.com'
-    url = 'https://' + host + '/stream/v1/tts'
-    # 设置HTTPS Headers。
-    httpHeaders = {
-        'Content-Type': 'application/json'
-        }
-    # 设置HTTPS Body。
-    body = {'appkey': appKey, 'token': token, 'text': text, 'format': format, 'sample_rate': sampleRate}
-    body = json.dumps(body)
-    print('The POST request body content: ' + body)
-    # Python 2.x请使用httplib。
-    # conn = httplib.HTTPSConnection(host)
-    # Python 3.x请使用http.client。
-    conn = http.client.HTTPSConnection(host)
-    conn.request(method='POST', url=url, body=body, headers=httpHeaders)
-    # 处理服务端返回的响应。
-    response = conn.getresponse()
-    print('Response status and response reason:')
-    print(response.status ,response.reason)
-    contentType = response.getheader('Content-Type')
-    print(contentType)
-    body = response.read()
-    if 'audio/mpeg' == contentType :
-        with open(audioSaveFile, mode='wb') as f:
-            f.write(body)
-        print('The POST request succeed!')
-    else :
-        print('The POST request failed: ' + str(body))
-    conn.close()
-appKey = 'KZChElSawT5Zue3n'
-token = 'fbb04d8f368e4394ac7172a1225c0720'
-text = '今天是周五,天气挺好的。'
-# 采用RFC 3986规范进行urlencode编码。
-textUrlencode = text
-# Python 2.x请使用urllib.quote。
-# textUrlencode = urllib.quote(textUrlencode, '')
-# Python 3.x请使用urllib.parse.quote_plus。
-textUrlencode = urllib.parse.quote_plus(textUrlencode)
-textUrlencode = textUrlencode.replace("+", "%20")
-textUrlencode = textUrlencode.replace("*", "%2A")
-textUrlencode = textUrlencode.replace("%7E", "~")
-print('text: ' + textUrlencode)
-audioSaveFile = '/Users/tzld/Desktop/video_rewriting/common/syAudio.MP3'
-format = 'MP3'
-sampleRate = 16000
-# GET请求方式
-processGETRequest(appKey, token, textUrlencode, audioSaveFile, format, sampleRate)
-# POST请求方式
-# processPOSTRequest(appKey, token, text, audioSaveFile, format, sampleRate)
+import random
+import re
+import time
+
+class TTS:
+
+    @classmethod
+    def get_pw_zm(cls, text):
+        max_retries = 3
+        for attempt in range(max_retries):
+            url = "https://zh.api.guiji.cn/avatar2c/tool/sec_tts"
+
+            payload = json.dumps({
+                "text": text,
+                "speaker_id": "160"
+            })
+            headers = {
+                'accept': 'application/json, text/plain, */*',
+                'accept-language': 'zh-CN',
+                'cache-control': 'no-cache',
+                'content-type': 'application/json',
+                'cookie': 'anylangIsLogin=true',
+                'origin': 'https://app.guiji.cn',
+                'pragma': 'no-cache',
+                'priority': 'u=1, i',
+                'referer': 'https://app.guiji.cn/',
+                'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',
+                'sec-ch-ua-mobile': '?0',
+                'sec-ch-ua-platform': '"macOS"',
+                'sec-fetch-dest': 'empty',
+                'sec-fetch-mode': 'cors',
+                'sec-fetch-site': 'same-site',
+                'token': '72912b4ac30b412cb19d2e835a678854'
+            }
+            wait_time = random.uniform(5, 20)
+            time.sleep(wait_time)
+            response = requests.request("POST", url, headers=headers, data=payload)
+            try:
+                response = response.json()
+                code = response["code"]
+                if code == 200:
+                    mp3 = response["data"]
+                    return mp3
+                else:
+                    if attempt == max_retries - 1:
+                        return None
+            except Exception:
+                if attempt == max_retries - 1:
+                    return None
+
+    @classmethod
+    def get_srt_format(cls, pw_srt_text, pw_url_sec):
+        segments = re.split(r'(,|。|!|?)', pw_srt_text)
+        segments = [segments[i] + segments[i + 1] for i in range(0, len(segments) - 1, 2)]
+        pw_url_sec = int(pw_url_sec) + 1
+        # 确定每段显示时间
+        num_segments = len(segments)
+        duration_per_segment = pw_url_sec / num_segments
+        srt_content = ""
+        start_time = 0.0
+        for i, segment in enumerate(segments):
+            end_time = start_time + duration_per_segment
+            srt_content += f"{i + 1}\n"
+            srt_content += f"{int(start_time // 3600):02}:{int((start_time % 3600) // 60):02}:{int(start_time % 60):02},{int((start_time % 1) * 1000):03} --> "
+            srt_content += f"{int(end_time // 3600):02}:{int((end_time % 3600) // 60):02}:{int(end_time % 60):02},{int((end_time % 1) * 1000):03}\n"
+            srt_content += f"{segment.strip()}\n\n"
+            start_time = end_time
+
+        print(srt_content)
+        return srt_content
+
+
+if __name__ == '__main__':
+    # text = "真是太实用了,分享给身边的准妈妈们吧!这些孕期禁忌一定要记住,赶紧转发给更多人,帮助更多的宝妈们。一起为宝宝的健康加油!"
+    # mp3 = TTS.get_pw_zm(text)
+    # command = [
+    #   'ffmpeg',
+    #   '-i', mp3,
+    #   '-q:a', '0',
+    #   '-map', 'a',
+    #   # '-codec:a', 'libmp3lame',  # 指定 MP3 编码器
+    #   "/Users/tzld/Desktop/video_rewriting/path/pw_video.mp3"
+    # ]
+    # subprocess.run(command)
+    # print("完成")
+    video_file = 'https://digital-public.obs.myhuaweicloud.com/vcm_server/20240715/KnOgRTYKvZbWD2EX_ms/FwA2SEh7DZQGlwAe.wav'
+    result = subprocess.run(
+        ["ffprobe", "-v", "error", "-show_entries", "format=duration",
+         "-of", "default=noprint_wrappers=1:nokey=1", video_file],
+        capture_output=True, text=True)
+    print(float(result.stdout))

+ 23 - 11
video_rewriting/video_prep.py

@@ -7,6 +7,9 @@ import time
 
 from datetime import datetime
 import concurrent.futures
+
+from common.tts_help import TTS
+
 sys.path.append(os.getcwd())
 
 from common import Material, Feishu, Common, Oss
@@ -171,18 +174,27 @@ class getVideo:
                         if gg_duration_total and gg_duration_total != 'None':  # 判断是否需要指定视频时长
                             new_video_path = FFmpeg.video_ggduration(new_video_path, video_path_url, pw_random_id, gg_duration_total)
                         if video_ending and video_ending != 'None':
-                            if ',' in video_ending:
-                                video_ending_list = video_ending.split(',')
-                            else:
-                                video_ending_list = [video_ending]
-                            ending = random.choice(video_ending_list)
-                            pw_list = Material.get_pwsrt_data("summary", pw_sheet, ending)  # 获取srt
-                            if pw_list:
-                                pw_id = pw_list["pw_id"]
-                                pw_srt = pw_list["pw_srt"]
-                                pw_url = PQ.get_pw_url(pw_id)
+                            if video_ending == "AI片尾引导":
+                                pw_srt_text = GPT4o.get_ai_pw(new_title)
+                                if pw_srt_text:
+                                    pw_url = TTS.get_pw_zm(pw_srt_text)
+                                    pw_url_sec = FFmpeg.get_videos_duration(pw_url)  # 获取片尾秒数
+                                    pw_srt = TTS.get_srt_format(pw_srt_text, pw_url_sec)
+                                else:
+                                    continue
                             else:
-                                Feishu.bot(mark, '机器自动改造消息通知', f'{task_mark}任务下片尾标示错误,请关注!!!!', name)
+                                if ',' in video_ending:
+                                    video_ending_list = video_ending.split(',')
+                                else:
+                                    video_ending_list = [video_ending]
+                                ending = random.choice(video_ending_list)
+                                pw_list = Material.get_pwsrt_data("summary", pw_sheet, ending)  # 获取srt
+                                if pw_list:
+                                    pw_id = pw_list["pw_id"]
+                                    pw_srt = pw_list["pw_srt"]
+                                    pw_url = PQ.get_pw_url(pw_id)
+                                else:
+                                    Feishu.bot(mark, '机器自动改造消息通知', f'{task_mark}任务下片尾标示错误,请关注!!!!', name)
                             for attempt in range(3):
                                 jpg_path = FFmpeg.video_png(new_video_path, video_path_url, pw_random_id)  # 生成视频最后一帧jpg
                                 if os.path.isfile(jpg_path):