相信你有在抖音或视频号刷到过这样的视频


这样由微信对话合成的视频,因为内容有趣,很多人都喜欢看,播放量都是很恐怖的。 做这样的视频也很赚钱,某位大v的收益

原理就是利用巨大的播放量,添加商品推广链接,有人通过链接购买商品,你赚取佣金​。

制作这样的视频,一般做法是:

  1. 去网上找对话素材
  2. 找一个模拟微信对话的工具
  3. 使用对话模拟器生成图片
  4. 对图片进行剪辑,生成视频

这样下来几个步骤其实挺麻烦的,并且制作每个视频其实都属于是重复劳作。

所以我们今天,教大家制作一个一键生成微信对话视频的工具,让你能够省时省力,抢占先机!

先看成品


只需要在界面点点点就能生成视频了,很方便有木有!

技术原理

用到的技术有

  1. 爬虫——从百度爬取图片
  2. ocr识别——识别图片文字
  3. 模拟微信对话工具
  4. server服务
  5. playwright自动化操作
  6. 图片处理
  7. 音频处理
  8. 视频处理
  9. 桌面gui

原来用到了这么多技术!不过不用担心,我都已经写好了,本文就是教大家怎么实现的,想直接用成品的同学,点击下面的链接获取!

链接:https://pan.baidu.com/s/1u78R9vhtnY5fwehlK17Z6Q?pwd=yb87 提取码:yb87

思路

  1. 根据关键字在百度图片批量下载数据
  2. 使用ocr识别图片中的文字
  3. 分析文字的位置,区分左右对话
  4. ocr精度有限,手工校对文字
  5. 启动一个模拟微信对话服务
  6. 进行自动化操作,将结果进行截图
  7. 将截图、音频进行合成视频

根据关键字在百度图片批量下载数据

我们从https://image.baidu.com/search搜索图片,提取出每张图片的地址,然后进行下载,主要代码如下(代码为主要部分代码)

url = (    "https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj"    "&ct=201326592&is=&fp=result&queryWord=%s&cl=2&lm=-1&ie=utf-8&oe=utf-8"    "&adpicid=&st=-1&z=&ic=&hd=&latest=&copyright=&word=%s&s=&se=&tab=&width=&height=&face=0"    "&istype=2&qc=&nc=1&fr=&expermode=&force=&pn=%s&rn=%d&gsm=1e&1594447993172="    % (search, search, str(pn), self.__per_page))# 设置header防403try:    time.sleep(self.time_sleep)    req = urllib.request.Request(url=url, headers=self.headers)    page = urllib.request.urlopen(req)    self.headers["Cookie"] = self.handle_baidu_cookie(        self.headers["Cookie"], page.info().get_all("Set-Cookie")    )    rsp = page.read()    page.close()except UnicodeDecodeError as e:    self.logger.error(e)    self.logger.error("-----UnicodeDecodeErrorurl:", url)

使用ocr识别图片中的文字

使用cnocr库,我们就能实现本地ocr识别,而不需要网络,代码如下

self.model = CnOcr(            det_model_name="ch_PP-OCRv3_det",        )out = self.model.ocr(    cv2.imdecode(self.read_file(f), -1),)for i in out:    i["score"] = float(i["score"])    i["position"] = i["position"].astype(float).tolist()    target_path.joinpath(file_name + ".json").write_text(        json.dumps(out, ensure_ascii=False, indent=4)    )

分析文字的位置,区分左右对话

我们基于文字的内容和位置,判断文字是属于

  • 标题——距离顶部的位置<30并字数不大于5
  • 同一句话——两句话的距离<50
  • 左边的人说的——句子位置离左边更近
  • 右边的人说的——句子位置离右边更近 主要逻辑如上,代码如下
res = []"""去掉标题栏"""if json_content and "中国" in json_content[0]["text"]:    # 中国联通行,去掉    x = json_content[0]["position"][0][0]    for i in range(1, len(json_content)):        if abs(json_content[i]["position"][0][0] - x) <= 20:            continue        else:            break    json_content = json_content[:i]

"""去掉‘微信’"""if (    json_content    and "微信" in json_content[0]["text"]    and len(json_content[0]["text"]) < 8):    json_content = json_content[1:]

"""首行是否为标题"""if not json_content:    return resleft_top_position = json_content[0]["position"][0]left_top_position_x = left_top_position[0]left_top_position_y = left_top_position[1]if left_top_position_y < 30 and len(json_content[0]["text"]) < 5:    # 认为是标题    res.append({"position": "title", "text": json_content[0]["text"]})    json_content = json_content[1:]

"""同一句话判断的阈值"""same_sentence_threshold = 30for i in range(1, len(json_content)):    same_sentence_threshold = min(        same_sentence_threshold,        abs(            json_content[i]["position"][0][1]            - json_content[i - 1]["position"][0][1]        ),    )same_sentence_threshold = max(50, same_sentence_threshold + 35)  # 误差

if not json_content:    return res"""找到左侧和右侧的位置"""left_around_position = min([i["position"][0][0] for i in json_content])right_around_position = max([i["position"][1][0] for i in json_content])

"""判断左右"""n = len(json_content)text = ""position_left = 0position_right = 0for i in range(n):    if re.compile(r"[0-9]{1,2}:[ ]{0,1}[0-9]{1,2}").findall(        json_content[i]["text"]    ):        # 微信时间        continue    if "微信" in json_content[i]["text"]:        # ”微信“标题        continue

    if (        i > 0        and abs(            json_content[i]["position"][0][1]            - json_content[i - 1]["position"][0][1]        )        < same_sentence_threshold    ):        # 认为当前话跟上一句话是同一句话        text += json_content[i]["text"]    else:        # 现在是另一个人说话,将上一个说的话保存        if text:            if res and res[-1]["position"] == "left":                # 如果上一句话是左边说的,我们更倾向于下一句话是右边的人说的                float_value = 25            else:                # 否则,更倾向于左边的人说的                float_value = -5            if not res:                # 第一句话更倾向于右边的人说的                float_value = 25            if abs(position_left - left_around_position) + float_value < abs(                position_right - right_around_position            ):                # 离左侧更近                res.append({"position": "left", "text": text})            else:                # 离右侧更近                res.append({"position": "right", "text": text})        text = json_content[i]["text"]        position_left = json_content[i]["position"][0][0]        position_right = json_content[i]["position"][1][0]if text:    if res and res[-1]["position"] == "left":        # 如果上一句话是左边说的,我们更倾向于下一句话是右边的人说的        float_value = 25    else:        # 否则,更倾向于左边的人说的        float_value = -5    if not res:        # 第一句话更倾向于右边的人说的        float_value = 25    if abs(position_left - left_around_position) + float_value < abs(        position_right - right_around_position    ):        # 离左侧更近        res.append({"position": "left", "text": text})    else:        # 离右侧更近        res.append({"position": "right", "text": text})if len(res) == 1:    return []return res

当然了,判断无法百分百正确,所以我们后续添加了手工修正

ocr精度有限,手工校对文字

基于flet库, 实现了ui界面


启动一个模拟微信对话服务

我们启动了一个fastapi服务,用于调用模拟微信对话

app = FastAPI()

app.mount(    "/static",    StaticFiles(directory=MAIN_PATH.joinpath("weixin_chat", "static")),    name="static",)

@app.route("/")def index(*args, **kwargs):    return HTMLResponse(        MAIN_PATH.joinpath(            "weixin_chat",            "index.html",        ).read_text(encoding="utf-8")    )

进行自动化操作,将结果进行截图

使用playwright库,打开浏览器,自动化进行操作,输入每条对话内容后,进行截图,保存到本地。

browser = playwright.chromium.launch(headless=True)context = browser.new_context()

page = context.new_page()page.goto("http://127.0.0.1:36999")page.wait_for_load_state()"""生成标题"""if formatted_jsons[0]["position"] == "title":    page.fill(title, formatted_jsons[0]["text"])    formatted_jsons = formatted_jsons[1:]else:    titles = ["佳佳", "小小", "♥", "❀", "啊呜", "奔波儿灞与灞波儿奔", "亲亲"]    page.fill(title, random.choice(titles))time.sleep(0.2)"""跳转到对话页"""page.click(    "#vueApp > div > div.edit-content > div.tab > ul > li:nth-child(2) > a")time.sleep(0.2)page.wait_for_selector(    "#tabContent2 > div > div.dialog-user-items > div:nth-child(1) > div > a.dialog-user-face-a > input[type=file]")"""清空对话"""page.on("dialog", lambda dialog: dialog.accept())page.click(clear_conv)time.sleep(0.2)"""选取头像"""photos = self.two_random_photo()page.set_input_files(my_photo, photos[0])time.sleep(0.2)page.set_input_files(second_photo, photos[1])time.sleep(0.2)_uuid = "".join(    re.compile(r"[0-9a-zA-Z\u4e00-\u9fa5]*").findall(        "".join(map(lambda e: e["text"], formatted_jsons))    ))save_path = WORK_PATH.joinpath(self.keyword, "images", _uuid[:15])save_path.mkdir(parents=True, exist_ok=True)index = 0for _json in formatted_jsons:    if _json["position"] == "left":        page.click(select_left)    else:        page.click(select_right)    time.sleep(0.2)    page.fill(input_words, _json["text"])    page.click(add_words)    time.sleep(0.2)    save_file = save_path.joinpath(f"{index}.jpg")    page.locator(target_area).screenshot(        path=save_file, quality=100, type="jpeg"    )    index += 1

将截图、音频进行合成视频

截图、音频合成视频,我们用到了moviepy,Pillow库,将图片按照名称,以固定的间隔拼合为视频,并在每个拼合的位置添加微信消息提示音。

images = glob.glob(str(path.joinpath("*.jpg")))if not images:    returnimages = sorted(images, key=lambda e: int(e.split("\\")[-1].split(".")[0]))images = self.resize_images(images)if not self.output_path:    video_path = WORK_PATH.joinpath(self.keyword, "output")    video_path.mkdir(parents=True, exist_ok=True)else:    video_path = Path(self.output_path)video_file = video_path.joinpath(str(path).split("\\")[-1] + ".mp4")fps = 1 / 1.5video_clip = ImageSequenceClip(images, fps=fps)during = video_clip.durationwechat_audio = AudioFileClip(    str(MAIN_PATH.joinpath("wechat_sound", "9411.mp3")))audio_clips = []i = 0while i < during:    audio_clips.append(wechat_audio.set_start(i))    i += 1.5final_audio_clip = CompositeAudioClip(audio_clips).set_fps(44100)video_clip = video_clip.set_audio(final_audio_clip.subclip(0, during))video_clip.write_videofile(str(video_file))self.logger.info(f"{video_file}生成完成")

这样我们的视频就制作完成啦。

成果

生成完后,文件保存在workspace/output文件夹中

效果⬇ 可能有的小伙伴会说:就这?真的有人看?

我还真做了测试,在抖音发了两个视频!

第一个只有167的播放量,第二个视频就冲到了1.6万!

所以完全是行得通的!

需要的小伙伴,点击⬇链接获取全部源代码!

链接:https://pan.baidu.com/s/1u78R9vhtnY5fwehlK17Z6Q?pwd=yb87 提取码:yb87

本文由 mdnice 多平台发布

自制副业神器!微信对话视频生成器相关推荐

  1. Windows神器 微信对话视频生成器

    简介 微信对话生成器是一款可以让你在朋友圈轻松装逼炫富的神器,你可以使用这款软件轻松制作微信对话.微信红包.等截图或视频,让你在朋友圈高逼格的装逼! 其次在微信对话制作界面,用户可以制作文本.图片.语 ...

  2. 虚拟聊天记录生成器,微信对话视频生成器,让微信对话以视频形式呈现!

    微信对话视频生成器是一款功能强大的工具,可以将微信聊天记录转化成生动有趣的视频.它不仅可以让用户在朋友圈或社交平台上展示自己的聊天趣事,还可以用于制作个性化的视频礼物.接下来,我们将介绍该工具的主要功 ...

  3. 【实测有效】一键生成微信对话视频,微信聊天记录生成器,

    微信对话视频生成器是一款非常实用的工具,它可以将平常的微信聊天记录转化为精彩纷呈的对话视频,让你的聊天更有趣.更生动!现在,无需任何专业技能,只需几步操作,你就可以快速生成属于自己的微信对话视频. 使 ...

  4. 微信对话在线生成器html5源码

    微信对话在线生成器html5源码的软件特点是: 一:操作简单,下载源码后双击 index.html 即可运行,不需要服务器 二:可以设置外观设置,手机状态栏,包括电量.时间.标题.背景等信息 三:可以 ...

  5. 《游戏学习》| 微信对话模拟生成器源码分析

    简介 微信对话生成器,是一款在线微信聊天对话制作的工具,它可以设置苹果或安卓状态栏,包括手机电量.手机时间等,还可以设置不同用户的角色,然后发送文字.语音.红包.转账等多种好玩的功能,可谓是一款娱乐制 ...

  6. 2020微信对话截图生成器,各种截图一键制作!

    前言 上次有朋友说想要个微商作图神器,找了几款觉得功能一般般,就没有发出来,今天又有朋友私信了,对比了这几款,选择中一款不错的给大家分享一下,软件是安卓版的,打开就是VIP,无需去登陆了,直接使用即可 ...

  7. 2022在线微信对话生成器源码,抖音微信聊天搞笑视频制作神器

    在线微信对话生成器源码,抖音微信聊天搞笑视频制作神器 微信对话生成器,是一款在线微信聊天对话制作的工具,它可以设置苹果或安卓状态栏,包括手机电量.手机时间等,还可以设置不同用户的角色,然后发送文字.语 ...

  8. 在线微信对话生成器源码 装逼神器

    在线微信对话生成器源码,抖音微信聊天搞笑视频制作神器 微信对话生成器,是一款在线微信聊天对话制作的工具,它可以设置苹果或安卓状态栏,包括手机电量.手机时间等,还可以设置不同用户的角色,然后发送文字.语 ...

  9. 微信对话生成脚本,一键生成视频=脚本+教程

    制作微信对话视频,一般做法是: 1. 去网上找对话素材 2. 找一个模拟微信对话的工具 3. 使用对话模拟器生成图片 4. 对图片进行剪辑,生成视频 这样下来几个步骤其实挺麻烦的,并且制作每个视频其实 ...

最新文章

  1. 红帽赞助的Linux发行版Fedora 33刚刚发布
  2. 打印机更换感光鼓单元k_SOHO打印机基础培训(成像原理)
  3. optee3.14中的异常向量表解读--中断处理解读
  4. akka 异常处理_使用Akka处理1000万条消息
  5. 99%的程序员都在用Lombok,原理竟然这么简单?我也手撸了一个!|建议收藏
  6. Material Design实现的美观的登录界面
  7. 2013年6月6日星期四
  8. JavaScript 框架这一年:React、Angular 们正在互相渗透
  9. 网络设备常用排障命令——Juniper vyatta 大河SDN
  10. AWT_Swing_图片Icon
  11. 详解:IDEA不能自动加载import问题
  12. ibatis的缓存机制
  13. Java ActiveMQ 讲解(二)Spring ActiveMQ整合+注解消息监听
  14. Python部署虚拟环境的利器——Virtualenv
  15. python与vb语言_vb.net和python区别是什么
  16. 阿里云服务器:配置 Docker 的 镜像加速器
  17. 【数据治理】数字治理的效度、温度、 尺度
  18. skynet框架应用 (十四) 登录服务
  19. python实现下载压缩包并且解压
  20. new relic_Datadog,SignalFX,New Relic,Wavefront –您应该选择哪个仪表板?

热门文章

  1. AI测试|天猫精灵智能音箱测试策略与方法
  2. NPDP知识推送-第一章新产品开发战略(2)
  3. 一键重装系统win7旗舰版系统教程
  4. AI 作画:Stable Diffusion 模型原理与实践
  5. 办理营业执照注册要什么费用
  6. 微信小程序之在线任务发布与接单平台(2)
  7. vb.net学习日记3.29
  8. 哄她开心的圣诞树html源码,复制粘贴就能实现~
  9. revit模型怎么在手机上看_e建筑手机版下载-e建筑(轻松查看CAD图纸和BIM模型)1.2.4 官方苹果版-东坡下载...
  10. __I、 __O 、__IO是什么意思?