抖音和视频号平台上,微信聊天内容转换成视频功能因其趣味性强而广受欢迎,观看量极高,众多用户因此获益。本文将揭示制作这类一键生成视频工具的方法,助力开启高效盈利途径。
热门视频潜力大
短视频平台上,微信对话合成视频颇受欢迎,观看次数显著,众多用户因其趣味性内容而关注。知名博主利用这类视频插入商品推广链接,成功赚取了可观的佣金,这一现象突显了其商业潜力,吸引了众多创作者尝试制作类似内容。
传统制作有难题
过去制作微信聊天视频的过程较为繁琐,涉及在线搜寻对话片段、寻找模拟软件、制作图片以及后续的剪辑工作。这些步骤不仅耗时费力,而且多为重复性劳动,导致工作效率不高,进而使得众多创作者难以高效完成作品制作。
工具制作新技术
该工具集成了多项技术。其爬虫功能可从百度获取图片和视频资源;OCR技术用于照片文字的识别,以便提取内容;模拟微信对话功能用于构建对话环境;server服务确保系统稳定运行;playwright技术用于自动化操作,优化工作流程;桌面GUI界面则便于用户操作。
数据下载提效率
<p><pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"> <span style="display: block;background: url("https://mmbiz.qpic.cn/mmbiz_svg/zZSYtpeVianTCibtUklhlFBD1Vsiabs2syn5mhW6hfq769uT1wnbSBTiaEsYnxhvPygrD7MHTb11oN7MeIiaXOTwicRWxmmCQ3pSm9/640?wx_fmt=svg") 10px 10px / 40px no-repeat rgb(250, 250, 250);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #383a42;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #fafafa;border-radius: 5px;">url = ( <span style="color: #50a14f;line-height: 26px;">"https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj"</span><br /> <span style="color: #50a14f;line-height: 26px;">"&ct=201326592&is=&fp=result&queryWord=%s&cl=2&lm=-1&ie=utf-8&oe=utf-8"</span><br /> <span style="color: #50a14f;line-height: 26px;">"&adpicid=&st=-1&z=&ic=&hd=&latest=©right=&word=%s&s=&se=&tab=&width=&height=&face=0"</span><br /> <span style="color: #50a14f;line-height: 26px;">"&istype=2&qc=&nc=1&fr=&expermode=&force=&pn=%s&rn=%d&gsm=1e&1594447993172="</span><br /> % (search, search, str(pn), self.__per_page)<br />)<br /><span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 设置header防403</span><br />try:<br /> time.sleep(self.time_sleep)<br /> req = urllib.request.Request(url=url, headers=self.headers)<br /> page = urllib.request.urlopen(req)<br /> self.headers[<span style="color: #50a14f;line-height: 26px;">"Cookie"</span>] = self.handle_baidu_cookie(<br /> self.headers[<span style="color: #50a14f;line-height: 26px;">"Cookie"</span>], page.info().get_all(<span style="color: #50a14f;line-height: 26px;">"Set-Cookie"</span>)<br /> )<br /> rsp = page.read()<br /> page.close()<br />except UnicodeDecodeError as e:<br /> self.logger.error(e)<br /> self.logger.error(<span style="color: #50a14f;line-height: 26px;">"-----UnicodeDecodeErrorurl:"</span>, url)<br /></code></pre></p>
利用百度图片搜索功能,通过关键词批量下载图片,获取图片链接并进行下载,此举为视频制作提供了丰富的素材。此方法显著减少了寻找图片所需的时间,使创作者能够迅速获得所需资源,从而将更多精力集中于视频内容的创作上。
<p><pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"> <span style="display: block;background: url("https://mmbiz.qpic.cn/mmbiz_svg/zZSYtpeVianTCibtUklhlFBD1Vsiabs2syn5mhW6hfq769uT1wnbSBTiaEsYnxhvPygrD7MHTb11oN7MeIiaXOTwicRWxmmCQ3pSm9/640?wx_fmt=svg") 10px 10px / 40px no-repeat rgb(250, 250, 250);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #383a42;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #fafafa;border-radius: 5px;">self.model = CnOcr(<br /> det_model_name=<span style="color: #50a14f;line-height: 26px;">"ch_PP-OCRv3_det"</span>,<br /> )<br />out = self.model.ocr(<br /> cv2.imdecode(self.read_file(f), -1),<br />)<br /><span style="color: #a626a4;line-height: 26px;">for</span> i <span style="color: #a626a4;line-height: 26px;">in</span> out:<br /> i[<span style="color: #50a14f;line-height: 26px;">"score"</span>] = <span style="color: #c18401;line-height: 26px;">float</span>(i[<span style="color: #50a14f;line-height: 26px;">"score"</span>])<br /> i[<span style="color: #50a14f;line-height: 26px;">"position"</span>] = i[<span style="color: #50a14f;line-height: 26px;">"position"</span>].astype(<span style="color: #c18401;line-height: 26px;">float</span>).tolist()<br /> target_path.joinpath(file_name + <span style="color: #50a14f;line-height: 26px;">".json"</span>).write_text(<br /> json.dumps(out, ensure_ascii=False, indent=4)<br /> )<br /></code></pre></p>
<b>文字识别与修正

cnocr 库支持本地OCR识别操作,操作简便且不依赖网络。然而,OCR的识别精度有所局限,因此需要对文字位置进行详细分析以区分对话的左右,并且需要加入人工校对步骤,以保证文字信息的精确性。
<p><pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"> <span style="display: block;background: url("https://mmbiz.qpic.cn/mmbiz_svg/zZSYtpeVianTCibtUklhlFBD1Vsiabs2syn5mhW6hfq769uT1wnbSBTiaEsYnxhvPygrD7MHTb11oN7MeIiaXOTwicRWxmmCQ3pSm9/640?wx_fmt=svg") 10px 10px / 40px no-repeat rgb(250, 250, 250);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #383a42;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #fafafa;border-radius: 5px;">res = []<span style="color: #50a14f;line-height: 26px;">""</span><span style="color: #50a14f;line-height: 26px;">"去掉标题栏"</span><span style="color: #50a14f;line-height: 26px;">""</span><br /><span style="color: #a626a4;line-height: 26px;">if</span> json_content and <span style="color: #50a14f;line-height: 26px;">"中国"</span> <span style="color: #a626a4;line-height: 26px;">in</span> json_content[0][<span style="color: #50a14f;line-height: 26px;">"text"</span>]:<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 中国联通行,去掉</span><br /> x = json_content[0][<span style="color: #50a14f;line-height: 26px;">"position"</span>][0][0]<br /> <span style="color: #a626a4;line-height: 26px;">for</span> i <span style="color: #a626a4;line-height: 26px;">in</span> range(1, len(json_content)):<br /> <span style="color: #a626a4;line-height: 26px;">if</span> abs(json_content[<span style="color: #50a14f;line-height: 26px;">"position"</span>][0][0] - x) <= 20:<br /> <span style="color: #c18401;line-height: 26px;">continue</span><br /> <span style="color: #a626a4;line-height: 26px;">else</span>:<br /> <span style="color: #c18401;line-height: 26px;">break</span><br /> json_content = json_content[:i]<br /><br /><span style="color: #50a14f;line-height: 26px;">""</span><span style="color: #50a14f;line-height: 26px;">"去掉‘微信’"</span><span style="color: #50a14f;line-height: 26px;">""</span><br /><span style="color: #a626a4;line-height: 26px;">if</span> (<br /> json_content<br /> and <span style="color: #50a14f;line-height: 26px;">"微信"</span> <span style="color: #a626a4;line-height: 26px;">in</span> json_content[0][<span style="color: #50a14f;line-height: 26px;">"text"</span>]<br /> and len(json_content[0][<span style="color: #50a14f;line-height: 26px;">"text"</span>]) < 8<br />):<br /> json_content = json_content[1:]<br /><br /><span style="color: #50a14f;line-height: 26px;">""</span><span style="color: #50a14f;line-height: 26px;">"首行是否为标题"</span><span style="color: #50a14f;line-height: 26px;">""</span><br /><span style="color: #a626a4;line-height: 26px;">if</span> not json_content:<br /> <span style="color: #c18401;line-height: 26px;">return</span> res<br />left_top_position = json_content[0][<span style="color: #50a14f;line-height: 26px;">"position"</span>][0]<br />left_top_position_x = left_top_position[0]<br />left_top_position_y = left_top_position[1]<br /><span style="color: #a626a4;line-height: 26px;">if</span> left_top_position_y < 30 and len(json_content[0][<span style="color: #50a14f;line-height: 26px;">"text"</span>]) < 5:<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 认为是标题</span><br /> res.append({<span style="color: #50a14f;line-height: 26px;">"position"</span>: <span style="color: #50a14f;line-height: 26px;">"title"</span>, <span style="color: #50a14f;line-height: 26px;">"text"</span>: json_content[0][<span style="color: #50a14f;line-height: 26px;">"text"</span>]})<br /> json_content = json_content[1:]<br /><br /><span style="color: #50a14f;line-height: 26px;">""</span><span style="color: #50a14f;line-height: 26px;">"同一句话判断的阈值"</span><span style="color: #50a14f;line-height: 26px;">""</span><br />same_sentence_threshold = 30<br /><span style="color: #a626a4;line-height: 26px;">for</span> i <span style="color: #a626a4;line-height: 26px;">in</span> range(1, len(json_content)):<br /> same_sentence_threshold = min(<br /> same_sentence_threshold,<br /> abs(<br /> json_content[<span style="color: #50a14f;line-height: 26px;">"position"</span>][0][1]<br /> - json_content[i - 1][<span style="color: #50a14f;line-height: 26px;">"position"</span>][0][1]<br /> ),<br /> )<br />same_sentence_threshold = max(50, same_sentence_threshold + 35) <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 误差</span><br /><br /><span style="color: #a626a4;line-height: 26px;">if</span> not json_content:<br /> <span style="color: #c18401;line-height: 26px;">return</span> res<br /><span style="color: #50a14f;line-height: 26px;">""</span><span style="color: #50a14f;line-height: 26px;">"找到左侧和右侧的位置"</span><span style="color: #50a14f;line-height: 26px;">""</span><br />left_around_position = min([i[<span style="color: #50a14f;line-height: 26px;">"position"</span>][0][0] <span style="color: #a626a4;line-height: 26px;">for</span> i <span style="color: #a626a4;line-height: 26px;">in</span> json_content])<br />right_around_position = max([i[<span style="color: #50a14f;line-height: 26px;">"position"</span>][1][0] <span style="color: #a626a4;line-height: 26px;">for</span> i <span style="color: #a626a4;line-height: 26px;">in</span> json_content])<br /><br /><span style="color: #50a14f;line-height: 26px;">""</span><span style="color: #50a14f;line-height: 26px;">"判断左右"</span><span style="color: #50a14f;line-height: 26px;">""</span><br />n = len(json_content)<br />text = <span style="color: #50a14f;line-height: 26px;">""</span><br />position_left = 0<br />position_right = 0<br /><span style="color: #a626a4;line-height: 26px;">for</span> i <span style="color: #a626a4;line-height: 26px;">in</span> range(n):<br /> <span style="color: #a626a4;line-height: 26px;">if</span> re.compile(r<span style="color: #50a14f;line-height: 26px;">"[0-9]{1,2}:[ ]{0,1}[0-9]{1,2}"</span>).findall(<br /> json_content[<span style="color: #50a14f;line-height: 26px;">"text"</span>]<br /> ):<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 微信时间</span><br /> <span style="color: #c18401;line-height: 26px;">continue</span><br /> <span style="color: #a626a4;line-height: 26px;">if</span> <span style="color: #50a14f;line-height: 26px;">"微信"</span> <span style="color: #a626a4;line-height: 26px;">in</span> json_content[<span style="color: #50a14f;line-height: 26px;">"text"</span>]:<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># ”微信“标题</span><br /> <span style="color: #c18401;line-height: 26px;">continue</span><br /><br /> <span style="color: #a626a4;line-height: 26px;">if</span> (<br /> i > 0<br /> and abs(<br /> json_content[<span style="color: #50a14f;line-height: 26px;">"position"</span>][0][1]<br /> - json_content[i - 1][<span style="color: #50a14f;line-height: 26px;">"position"</span>][0][1]<br /> )<br /> < same_sentence_threshold<br /> ):<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 认为当前话跟上一句话是同一句话</span><br /> text += json_content[<span style="color: #50a14f;line-height: 26px;">"text"</span>]<br /> <span style="color: #a626a4;line-height: 26px;">else</span>:<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 现在是另一个人说话,将上一个说的话保存</span><br /> <span style="color: #a626a4;line-height: 26px;">if</span> text:<br /> <span style="color: #a626a4;line-height: 26px;">if</span> res and res[-1][<span style="color: #50a14f;line-height: 26px;">"position"</span>] == <span style="color: #50a14f;line-height: 26px;">"left"</span>:<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 如果上一句话是左边说的,我们更倾向于下一句话是右边的人说的</span><br /> float_value = 25<br /> <span style="color: #a626a4;line-height: 26px;">else</span>:<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 否则,更倾向于左边的人说的</span><br /> float_value = -5<br /> <span style="color: #a626a4;line-height: 26px;">if</span> not res:<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 第一句话更倾向于右边的人说的</span><br /> float_value = 25<br /> <span style="color: #a626a4;line-height: 26px;">if</span> abs(position_left - left_around_position) + float_value < abs(<br /> position_right - right_around_position<br /> ):<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 离左侧更近</span><br /> res.append({<span style="color: #50a14f;line-height: 26px;">"position"</span>: <span style="color: #50a14f;line-height: 26px;">"left"</span>, <span style="color: #50a14f;line-height: 26px;">"text"</span>: text})<br /> <span style="color: #a626a4;line-height: 26px;">else</span>:<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 离右侧更近</span><br /> res.append({<span style="color: #50a14f;line-height: 26px;">"position"</span>: <span style="color: #50a14f;line-height: 26px;">"right"</span>, <span style="color: #50a14f;line-height: 26px;">"text"</span>: text})<br /> text = json_content[<span style="color: #50a14f;line-height: 26px;">"text"</span>]<br /> position_left = json_content[<span style="color: #50a14f;line-height: 26px;">"position"</span>][0][0]<br /> position_right = json_content[<span style="color: #50a14f;line-height: 26px;">"position"</span>][1][0]<br /><span style="color: #a626a4;line-height: 26px;">if</span> text:<br /> <span style="color: #a626a4;line-height: 26px;">if</span> res and res[-1][<span style="color: #50a14f;line-height: 26px;">"position"</span>] == <span style="color: #50a14f;line-height: 26px;">"left"</span>:<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 如果上一句话是左边说的,我们更倾向于下一句话是右边的人说的</span><br /> float_value = 25<br /> <span style="color: #a626a4;line-height: 26px;">else</span>:<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 否则,更倾向于左边的人说的</span><br /> float_value = -5<br /> <span style="color: #a626a4;line-height: 26px;">if</span> not res:<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 第一句话更倾向于右边的人说的</span><br /> float_value = 25<br /> <span style="color: #a626a4;line-height: 26px;">if</span> abs(position_left - left_around_position) + float_value < abs(<br /> position_right - right_around_position<br /> ):<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 离左侧更近</span><br /> res.append({<span style="color: #50a14f;line-height: 26px;">"position"</span>: <span style="color: #50a14f;line-height: 26px;">"left"</span>, <span style="color: #50a14f;line-height: 26px;">"text"</span>: text})<br /> <span style="color: #a626a4;line-height: 26px;">else</span>:<br /> <span style="color: #a0a1a7;font-style: italic;line-height: 26px;"># 离右侧更近</span><br /> res.append({<span style="color: #50a14f;line-height: 26px;">"position"</span>: <span style="color: #50a14f;line-height: 26px;">"right"</span>, <span style="color: #50a14f;line-height: 26px;">"text"</span>: text})<br /><span style="color: #a626a4;line-height: 26px;">if</span> len(res) == 1:<br /> <span style="color: #c18401;line-height: 26px;">return</span> []<br /><span style="color: #c18401;line-height: 26px;">return</span> res<br /></code></pre></p>
<b>视频合成见成效
您是否考虑过利用这款便捷的微信对话视频生成器来制作个人视频内容?欢迎在评论区留下您的见解。同时,请不要忘记为这篇文章点赞及转发。
<p><pre data-tool="mdnice编辑器" style="margin-top: 10px;margin-bottom: 10px;border-radius: 5px;box-shadow: rgba(0, 0, 0, 0.55) 0px 2px 10px;"> <span style="display: block;background: url("https://mmbiz.qpic.cn/mmbiz_svg/zZSYtpeVianTCibtUklhlFBD1Vsiabs2syn5mhW6hfq769uT1wnbSBTiaEsYnxhvPygrD7MHTb11oN7MeIiaXOTwicRWxmmCQ3pSm9/640?wx_fmt=svg") 10px 10px / 40px no-repeat rgb(250, 250, 250);height: 30px;width: 100%;margin-bottom: -7px;border-radius: 5px;"></span><code style="overflow-x: auto;padding: 16px;color: #383a42;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;font-size: 12px;-webkit-overflow-scrolling: touch;padding-top: 15px;background: #fafafa;border-radius: 5px;">app = FastAPI()<br /><br />app.mount(<br /> <span style="color: #50a14f;line-height: 26px;">"/static"</span>,<br /> StaticFiles(directory=MAIN_PATH.joinpath(<span style="color: #50a14f;line-height: 26px;">"weixin_chat"</span>, <span style="color: #50a14f;line-height: 26px;">"static"</span>)),<br /> name=<span style="color: #50a14f;line-height: 26px;">"static"</span>,<br />)<br /><br />@app.route(<span style="color: #50a14f;line-height: 26px;">"/"</span>)<br />def index(*args, **kwargs):<br /> <span style="color: #c18401;line-height: 26px;">return</span> HTMLResponse(<br /> MAIN_PATH.joinpath(<br /> <span style="color: #50a14f;line-height: 26px;">"weixin_chat"</span>,<br /> <span style="color: #50a14f;line-height: 26px;">"index.html"</span>,<br /> ).read_text(encoding=<span style="color: #50a14f;line-height: 26px;">"utf-8"</span>)<br /> )<br /></code></pre></p> |
|