前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【玩转腾讯云】【腾讯云语音合成TTS】短视频批量生成器

【玩转腾讯云】【腾讯云语音合成TTS】短视频批量生成器

原创
作者头像
01player
修改2020-05-07 20:16:08
7.4K1
修改2020-05-07 20:16:08
举报

背景


疫情期间发现一个有趣的现象,有一类短视频父母刷抖音的时候经常会看到,这类视频只有一个或多个简单的背景图片,配合一段文字录音,讲一段新闻、故事、或者鸡汤。我想可能是他们对纯文本或者纯语音的内容都不感兴趣,更容易接受短视频这样简单的内容形式。又想到腾讯云有语音合成的产品,加上ffmpeg等视频处理工具,是不是可以批量生成一些这类短视频呢。

要求


1. 了解linux shell

2. 了解python

准备


1. Mac或linux系统

2. 需要播报的文本内容

3. 需要使用的背景图片

过程


以mac系统环境为例:

1. 安装环境

以mac系统环境为例:

安装ffmpeg

brew install ffmpeg

2. 需要播报的文本内容

这里以深圳垃圾分类的相关内容为例,保存为content.txt

可回收物,是指可循环利用和资源化利用的废纸、废塑料、废玻璃、废金属、废弃织物、废弃电子产品等;有害垃圾,是指对人体健康或者自然环境造成直接或者潜在危害应当专门处置的废电池、废灯管、弃置药品、废杀虫剂、废油漆、废日用化学品、废水银产品等;其他垃圾,是指除可回收物、有害垃圾之外的其他废弃物。

3. 需要使用的背景图片

自行准备,保存为pic.jpg

4. 参考腾讯云语音合成文档开通腾讯云语音合成服务

5. 下载腾讯云语音合成python SDK

6. 语音合成脚本

使用的默认参数获取文本内容的语音合成结果,如果想调整合成的效果可以参考腾讯云语音合成相关文档。

这里使用一句话语音合成接口,由于该接口有字数限制,主要思路是,将待合成的文本,按照少于字数限制的最后一个标点切分,这样切分出来的句子既能满足字数限制,又能尽可能保证合成时一句话上下文的完整性。

# coding=utf8
import base64
import math
import struct

from tencentcloud.common import credential
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.tts.v20190823 import tts_client, models

SECRET_ID = "your-secret-id"
SECRET_KEY = "your-secret-key"

def int32_to_4byte(int32):
    byte_list = [0, 0, 0, 0]
    for i in range(4):
        base = math.pow(256, (3 - i))
        byte_list[3 - i] = int(int32 / base)
        int32 = int32 % base
    return byte_list

def request_tencent_tts(text):
    cred = credential.Credential(SECRET_ID, SECRET_KEY)
    client = tts_client.TtsClient(cred, "ap-shanghai")
    request = models.TextToVoiceRequest()
    request.Text = text
    request.SessionId = "session_id_123"
    request.ModelType = 1
    request.Volume = 0
    request.Speed = 0
    request.ProjectId = 0
    request.VoiceType = 0
    request.PrimaryLanguage = 1
    request.SampleRate = 16000
    request.Codec = "wav"
    response = client.TextToVoice(request)
    audio = base64.b64decode(response.Audio)
    return audio

def tts(content_fname, wav_fname):
    tts_split_char = set([',', '。', ';'])
    with open(content_fname, "r", encoding="utf8") as f:
        content = f.read()
        step = 110
        text = ""
        last_split = 0
        last_punctuation = 0
        all_wav_pcm = b''
        audio_list = []
        for i in range(len(content)):
            if content[i] in tts_split_char:
                last_punctuation = i
            if i - last_split >= 110 or i == len(content) - 1:
                if content[i] in tts_split_char:
                    last_punctuation = i
                text = content[last_split:last_punctuation]
                if text != "":
                    #print("text: %s" % text)
                    last_split = last_punctuation + 1
                    audio = request_tencent_tts(text)
                    audio_list.append(audio)

        pcm = []
        head = []
        for audio in audio_list:
            print("audio length: %s" % len(audio))
            pcm = pcm + list(audio[44:])
            head = list(audio[:44])
            string = ""
            for c in head:
                string = string + " " + str(c)
            print(string)

        # 拿最后一个片段的文件头修改后拼接
        file_length = len(pcm) + 44
        byte_list = int32_to_4byte(file_length - 8)
        head[4] = byte_list[0]
        head[5] = byte_list[1]
        head[6] = byte_list[2]
        head[7] = byte_list[3]

        byte_list = int32_to_4byte(len(pcm))
        head[40] = byte_list[0]
        head[41] = byte_list[1]
        head[42] = byte_list[2]
        head[43] = byte_list[3]

        wav = head + pcm
            
        with open(wav_fname, 'wb') as f:
            for byte in wav:
                f.write(struct.pack('B', byte))

if __name__ == "__main__"    
    tts("content.txt", "content.wav")

7. 根据语音合成结果生成字幕srt脚本

主要思路是以逗号、句号等标点符号切分整个文本,得到N个文本片段。以每个片段在整段文本中的比例为锚点,在上一步生成的语音文件中,找到同样比例的时间点,作为该段字幕出现的时间点,这样字幕与语音就对齐了。

# coding=utf8
from pydub import AudioSegment

def timestamp_format(msecond):
    sec, msec = divmod(msecond, 1000)
    minute, sec = divmod(sec, 60)
    hour, minute = divmod(minute, 60)
    timestamp_hour_min_sec = "{0:02d}:{1:02d}:{2:02d},{3}".format(hour, minute, sec, msec)
    print("timestamp_hour_min_sec: %s" % timestamp_hour_min_sec)
    return timestamp_hour_min_sec

def srt(speech_duration_msecond, content_fname, srt_fname):
    with open(content_fname, 'r') as f:
        content = f.read()
    srt_split_char = set([',', '。', ':'])
    srt_text_list = []
    srt_timestamp_list = ['00:00:00,0']
    length = len(content)
    last_split_char_index = 0
    for i in range(length):
        if content[i] in srt_split_char:
            timestamp_msecond = int(i / length * speech_duration_msecond)
            item = content[last_split_char_index : i]
            last_split_char_index = i + 1
            srt_text_list.append(item)
            timestamp_hour_min_sec = timestamp_format(timestamp_msecond)
            srt_timestamp_list.append(timestamp_hour_min_sec)

    with open(srt_fname, 'w', encoding='utf8') as f:
        for i in range(len(srt_text_list)):
            item_timestamp_begin = srt_timestamp_list[i]
            item_timestamp_end = srt_timestamp_list[i + 1]
            string = "{}\n{} --> {}\n{}\n\n".format(i + 1, item_timestamp_begin, item_timestamp_end, srt_text_list[i])
            f.write(string)

def get_wav_duration(fname):
    sound= AudioSegment.from_wav(fname)
    duration = sound.duration_seconds * 1000  # 音频时长(ms)
    return duration

if __name__ == "__main__":
    duration = get_wav_duration('content.wav')
    print("duration: %d" % duration)
    srt(duration, 'content.txt', 'content.srt')

8. 将srt字幕转换成ass字幕

由于srt字幕不支持直接合成到视频中直接播放,需要先转换成ass字幕。

ffmpeg -i content.srt content.ass

9. 生成视频

通过ffmpeg将语音文件content.wav,字幕文件content.ass,背景图片pic.jpg,合成一个完整的视频,ffmpeg相关命令请搜索相关文档。

ffmpeg -threads 2 -y -loop 1 -i pic.jpg -r 25 -i content.wav -vf ass=content.ass output.mp4

10. 完成

按顺序执行上面的操作,就可以批量导入文本和图片,批量生成一批图文结合带语音播报的短视频内容。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 要求
  • 准备
  • 过程
    • 1. 安装环境
      • 2. 需要播报的文本内容
        • 3. 需要使用的背景图片
          • 4. 参考腾讯云语音合成文档开通腾讯云语音合成服务
            • 5. 下载腾讯云语音合成python SDK
              • 6. 语音合成脚本
                • 7. 根据语音合成结果生成字幕srt脚本
                  • 8. 将srt字幕转换成ass字幕
                    • 9. 生成视频
                      • 10. 完成
                      相关产品与服务
                      语音合成
                      语音合成(Text To Speech,TTS)满足将文本转化成拟人化语音的需求,打通人机交互闭环。提供多场景、多语言的音色选择,支持 SSML 标记语言,支持自定义音量、语速等参数,让发音更专业、更符合场景需求。语音合成广泛适用于智能客服、有声阅读、新闻播报、人机交互等业务场景。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档