python 录音本地转文字_用Python将抖音视频转换为字符视频

字符视频就是画面全部由字符组成的,

那么用代码怎么实现的呢?下面用python实现,话不多说,直接上干货。

代码实现详解

其实总体思路分为3个步骤:

1.将原视频分割成若干个图片以及分离出音频

2.将每张图片转为字符画图片(重点部分)

3.将若干个字符画图片和音频合并成新的视频(字符视频)将原视频分割成若干个图片以及分离出音频

这个过程我们可以用python调用ffmpeg工具进行切割,ffmpeg是专门处理音视频的工具库。可以在ffmpeg官网下载可执行文件放在程序的当前目录

分离音频命令为:ffmpeg.exe -i filename -vn temp.mp3#分离音频

slice_audio_cmd = 'ffmpeg.exe -i {0} -vn temp.mp3'.format(src_file)

os.system(slice_audio_cmd)

分割视频成若干图片的命令为:ffmpeg.exe -i filename -r 24 temp_pic/%06d.jpeg#切割成图片

slice_pic_cmd = 'ffmpeg.exe -i {0} -r 24 temp_pic/%06d.jpeg'.format(src_file)

os.system(slice_pic_cmd)

将分割出来的图片和音频临时存储起来,为了后面若干图片转字符图片效率及速度有所提高,还需将分割后的图片转为缩略图,就是改变图片的尺寸

这里使用python的PIL图形处理库来进行缩略图转化,同样将缩略图临时存储起来def create_thumbnail(src_dir, dst_dir):

picts_list = sorted(os.listdir(src_dir))

for picture in picts_list:

base_name = os.path.basename(picture)

img = Image.open(os.path.join(src_dir, picture))

size = 200, 200

img.thumbnail(size, Image.ANTIALIAS)

img.save(os.path.join(dst_dir, base_name))将每张图片转为字符画图片

如何将一张图片转为字符形式呢?其实很简单,分3步:

1.将图片转为灰度图

2.将灰度图的每个像素点替换为相应的字符

3.将所有替换后的字符画成一张字符图片

1.将图片转为灰度图

灰度图,Gray Scale Image 或是Grey Scale Image,又称灰阶图。把白色与黑色之间按对数关系分为若干等级,称为灰度。灰度分为256阶

公式为:Gray = R0.299 + G0.587 + B*0.114

同样在python中可以用PIL库直接转灰度:def load_picture(filename):

# Gray = R*0.299 + G*0.587 + B*0.114

img = Image.open(filename).convert('L')

(x, y) = img.size

pixels = list(img.getdata())

img.close()

return (pixels, x, y)

2.将灰度图的每个像素点替换为相应的字符

这里如何替换呢?可以根据灰阶值来替换为我们自己设定的字符,例如:symbols = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,"^`'. ")

从上面列表可以看到:越靠前的越密集,越往后越稀疏,于是我们根据灰阶值的大小按比例取列表中的字符,灰阶值越大,取越靠后的字符,这样图片轮廓才能更好的清晰显示

为了是转化后的字符图片看起来不密集以及提高转化时间,我这里将每间隔1个像素来替换字符,初始还要指定图片的边框及尺寸,这些参数可以自行调整,具体展示如下代码:def create_ascii_picture(pixels, symbols, dest_name, x_size, y_size):

scale= 4 # 长宽扩大倍数

border = 1 # 边框宽度

interval_pixel = 2 #原图片间隔多少个像素点来填充

img = Image.new('L',

(x_size*scale + 2*border,

y_size*scale + 2*border),

255)

fnt = ImageFont.truetype('DejaVuSansMono.ttf', int(scale*3))

t = ImageDraw.Draw(img)

x = border

y = border

for j in range(0, y_size, interval_pixel):

for i in range(0, x_size, interval_pixel):

t.text((x, y),

symbols[int(pixels[j*x_size + i]/256 * len(symbols))],

font=fnt,

fill=0

)

x += scale * interval_pixel

x = border

y += scale * interval_pixel

img.save(dest_name, "JPEG")

3.将所有替换后的字符画成一张字符图片

这步只需调用PIL库的save方法,如上面代码最后一行。

同样,我们将转化后的字符图片临时保存起来。

至此第2大步完成,即:将一张图片转为字符图片完成将若干个字符画图片和音频合并成新的视频(字符视频)

这里也是使用ffmpeg工具进行合成,命令为:ffmpeg -threads 2 -start_number 000001 -r 24 -i 路径名/%06d.jpeg -i temp.mp3 -vcodec mpeg4 生成的文件名merge_ascii_video_cmd = 'ffmpeg -threads 2 -start_number 000001 -r 24 -i {0}/%06d.jpeg -i temp.mp3 -vcodec mpeg4 {1}'.format('temp_ascii', dst_name)

os.system(merge_ascii_video_cmd)

这一步完成后,字符视频已经生成了。最后还需删除一些临时的文件及文件夹。

完整代码展示from PIL import Image, ImageDraw, ImageFont

import os, sys

import shutil

symbols = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,"^`'. ")

def ascii_art_convert(src_dir, dest_dir):

print('开始生成...')

picts_list = sorted(os.listdir(src_dir))

len_picts = len(picts_list)

i = 0

for picture in picts_list:

(pixels, x_size, y_size) = load_picture(os.path.join(src_dir, picture))

#生成字符画图片

create_ascii_picture(pixels, symbols, os.path.join(dest_dir, picture), x_size, y_size)

print('正在生成中... {0}/{1}'.format(i, len_picts))

i += 1

def create_thumbnail(src_dir, dst_dir):

picts_list = sorted(os.listdir(src_dir))

for picture in picts_list:

base_name = os.path.basename(picture)

img = Image.open(os.path.join(src_dir, picture))

size = 200, 200

img.thumbnail(size, Image.ANTIALIAS)

img.save(os.path.join(dst_dir, base_name))

def load_picture(filename):

# Gray = R*0.299 + G*0.587 + B*0.114

img = Image.open(filename).convert('L')

(x, y) = img.size

pixels = list(img.getdata())

img.close()

return (pixels, x, y)

def create_ascii_picture(pixels, symbols, dest_name, x_size, y_size):

scale = 4 # 长宽扩大倍数

border = 1 # 边框宽度

interval_pixel = 2 #原图片间隔多少个像素点来填充

img = Image.new('L',

(x_size*scale + 2*border,

y_size*scale + 2*border),

255)

fnt = ImageFont.truetype('DejaVuSansMono.ttf', int(scale*3))

t = ImageDraw.Draw(img)

x = border

y = border

for j in range(0, y_size, interval_pixel):

for i in range(0, x_size, interval_pixel):

t.text( (x, y),

symbols[int(pixels[j*x_size + i]/256 * len(symbols))],

font=fnt,

fill=0

)

x += scale * interval_pixel

x = border

y += scale * interval_pixel

img.save(dest_name, "JPEG")

def start_convert(src_file):

if not os.path.exists('temp_pic'):

os.mkdir('temp_pic')

if not os.path.exists('temp_thum'):

os.mkdir('temp_thum')

if not os.path.exists('temp_ascii'):

os.mkdir('temp_ascii')

#分离音频

slice_audio_cmd = 'ffmpeg.exe -i {0} -vn temp.mp3'.format(src_file)

os.system(slice_audio_cmd)

#切割成图片

slice_pic_cmd = 'ffmpeg.exe -i {0} -r 24 temp_pic/%06d.jpeg'.format(src_file)

os.system(slice_pic_cmd)

#生成缩略图

create_thumbnail('temp_pic', 'temp_thum')

#生成字符画

ascii_art_convert('temp_thum', 'temp_ascii')

#合成字符视频

dst_name = os.path.join(os.path.dirname(src_file), 'ascii_' + os.path.basename(src_file))

merge_ascii_video_cmd = 'ffmpeg -threads 2 -start_number 000001 -r 24 -i {0}/%06d.jpeg -i temp.mp3 -vcodec mpeg4 {1}'.format('temp_ascii', dst_name)

os.system(merge_ascii_video_cmd)

print('生成完成!')

if os.path.exists('temp_pic'):

shutil.rmtree('temp_pic')

if os.path.exists('temp_thum'):

shutil.rmtree('temp_thum')

if os.path.exists('temp_ascii'):

shutil.rmtree('temp_ascii')

if os.path.exists('temp.mp3'):

os.remove('temp.mp3')

if __name__ == '__main__':

src_file = sys.argv[1]

start_convert(src_file)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值