多线程的音频打标记的python实现(原创)

时间:2022-12-23 09:06:16

技术难度:

①需要一个UI界面,并且其中可进行相关参数的自调,最开始使用的是pygame的框架,后来转用tk界面;

②需要可以播放音频文件,MP3、WMA等格式;

③需要在播放音频的同时进行打标签操作,多线程技术;

④对音频进行相关拆分、叠加、重组,使用ffmpeg库进行相关操作;

一,UI界面

多线程的音频打标记的python实现(原创)

多线程的音频打标记的python实现(原创)

多线程的音频打标记的python实现(原创)

二,文件内容

多线程的音频打标记的python实现(原创)

使用 双击启动音频标记程序.bat 文件进行相对位置的文件启动,并且在 lib 中把所需的 ffmpeg 文件都已加载进去

三,程序源码

其中使用 threading 库的多线程功能,并且也使用到tk按钮中传递对象的功能。

 #-*- coding:utf-8 -*-
#edited by Mufasa
#文本标记软件 # import pygame #已经确定
import time
import threading
import tkinter,time,decimal,math,string,os
import tkinter.filedialog
import shutil
import tkinter as tk
import subprocess
from pydub import AudioSegment #已经确定 def out_comma(data,num_1,num_2):
txt=''
if len(data)==1:
for n in range(num_2):
txt=txt+data[0]+','
txt=txt[:-1]+'。'
else:
for i in data:
for n in range(num_1):
txt=txt+i+','
if num_1!=0:
txt=txt[:-1]+'。'
for n in range(num_2):
for i in data:
txt=txt+i+','
txt=txt[:-1]+'。'
return txt class assist():
def write_txt_data(data,path):
ls = os.linesep
#data 为数组类型
fobj = open(path,'w')
fobj.writelines(['%s%s'%(x,ls)for x in data])
fobj.close()
def read_txt_data(path):
fobj = open(path,'r')
string = []
for eachline in fobj:
if eachline[:-1] != '':
string.append(eachline[:-1])
fobj.close()
return string class out_aboutcode(tk.Toplevel):
def __init__(self):
super().__init__()
self.title('关于程序')# 弹窗界面
self.setup_UI()
def setup_UI(self):
row1 = tk.Frame(self)
row1.pack(fill="x")
# tk.Label(row1, text='欢迎使用音频标记软件!软件基于Python36设计\n\n使用说明:\n1,先选择需要进行标记的音频文件;\n2,点击——标记音频按钮,开始进行标记其中[ , ]符为小段标记点,[ . ]为大段标记点;\n3,标记的音频播放完毕后,点击—生成标记按钮,直接转换成标记文件并存储在\\data\\文件名\\目录下;\n\n欢迎使用').pack(side=tk.LEFT)
tk.Label(row1, text='欢迎使用音频标记软件!软件基于Python36设计\n\n使用说明:\n1,先点击[ 选择音频 ],选定您要进行标记的音频文件(默认支持MP3和wav格式)\n2,点击[ 标记音频 ],在文件的文本输入框中输入 , . 这两种符号分别进行小段和大段标记\n3,点击[ 生成标记 ],将音频的标记信息进行存储\n4,点击[ 设置音频 ],对音频的播放模式进行个性化设置\n\n祝使用愉快(*^_^*)').pack(side=tk.LEFT) row4 = tk.Frame(self)
row4.pack(fill="x")
tk.Button(row4, text="关闭窗口", command=self.cancel).pack(side=tk.RIGHT)
def cancel(self):
self.destroy() '''
data_set.txt
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
程序A ["逗号次数","逗号停顿","句号次数","句号停顿" , "大段次数" , "大段停顿" , "全体音频文件播放次数" , "产生此音频"]
[3,0,3,0,1,1,2,1]
A 0 1 2 3
[3,0,3,0,1,1,2,1,3,0,0,0,1,1,0,1] ["3","0","3","0","1","1","2","1","3","0","0","0","1","1","0","1"] [3,0,0,0,1,1,0,1]
程序B ["逗号次数","逗号停顿","句号次数","句号停顿" , "大段次数" , "大段停顿" , "全体音频文件播放次数" , "产生此音频"]
''' class out_setconfig(tk.Toplevel):
def __init__(self):
super().__init__()
self.title('参数设置')# 弹窗界面
self.data_set_path = os.path.dirname(os.path.realpath(__file__))+"\\data_set.txt"
isExists = os.path.exists(self.data_set_path )
if isExists == False: #bug,之前没有设置
self.setup_eror()
else:
self.setup_UI() def setup_eror(self):
row1 = tk.Frame(self)
row1.pack(fill="x")
tk.Label(row1, text='程序第一次运行!\n\n已进行参数初始化操作\n').pack(side=tk.LEFT)
row4 = tk.Frame(self)
row4.pack(fill="x")
assist.write_txt_data(["","","","","","","","","","","","","","","",""],self.data_set_path )
tk.Button(row4, text="关闭窗口", command=self.cancel).pack(side=tk.RIGHT)
def setup_UI(self): self.A00 = tk.StringVar()
self.A01 = tk.StringVar()
self.A10 = tk.StringVar()
self.A11 = tk.StringVar()
self.A20 = tk.StringVar()
self.A21 = tk.StringVar()
self.A30 = tk.StringVar()
# self.chvarEn = tk.IntVar()
self.A31 = tk.IntVar() self.B00 = tk.StringVar()
self.B01 = tk.StringVar()
self.B10 = tk.StringVar()
self.B11 = tk.StringVar()
self.B20 = tk.StringVar()
self.B21 = tk.StringVar()
self.B30 = tk.StringVar()
self.B31 = tk.IntVar() data = assist.read_txt_data(self.data_set_path)
# print(data)
self.A00.set(data[0])
self.A01.set(data[1])
self.A10.set(data[2])
self.A11.set(data[3])
self.A20.set(data[4])
self.A21.set(data[5])
self.A30.set(data[6])
# d = int(data[7])
# self.A31.set(d) self.B00.set(data[8])
self.B01.set(data[9])
self.B10.set(data[10])
self.B11.set(data[11])
self.B20.set(data[12])
self.B21.set(data[13])
self.B30.set(data[14])
# d = int(data[15])
# self.B31.set(d)
# self.B31.set(int(data[15])) row1 = tk.Frame(self)
row1.pack(fill="x") tk.Label(row1,text='程序A',width=30 ).grid(row=0,column=0,columnspan=2)
tk.Label(row1,text='逗号次数:',width=15).grid(row=1,column=0)
tk.Label(row1,text='逗号停顿(秒):',width=15).grid(row=2,column=0)
tk.Label(row1,text='句号次数:',width=15).grid(row=3,column=0)
tk.Label(row1,text='句号停顿(秒)',width=15).grid(row=4,column=0)
tk.Label(row1,text='括号次数',width=15).grid(row=5,column=0)
tk.Label(row1,text='括号停顿(秒)',width=15).grid(row=6,column=0)
tk.Label(row1,text='全部音频次数',width=15).grid(row=7,column=0)
tk.Label(row1,text='是否生成音频',width=15).grid(row=8,column=0) tk.Entry(row1, textvariable=self.A00, width=13).grid(row=1,column=1)
tk.Entry(row1, textvariable=self.A01, width=13).grid(row=2,column=1)
tk.Entry(row1, textvariable=self.A10, width=13).grid(row=3,column=1)
tk.Entry(row1, textvariable=self.A11, width=13).grid(row=4,column=1)
tk.Entry(row1, textvariable=self.A20, width=13).grid(row=5,column=1)
tk.Entry(row1, textvariable=self.A21, width=13).grid(row=6,column=1)
tk.Entry(row1, textvariable=self.A30, width=13).grid(row=7,column=1)
checkA = tk.Checkbutton(row1, text="播放", variable=self.A31)
checkA.select()
checkA.grid(column=1, row=8, sticky=tk.W) tk.Label(row1,text='程序B',width=30 ).grid(row=0,column=2,columnspan=2)
tk.Label(row1,text='逗号次数:',width=15).grid(row=1,column=2)
tk.Label(row1,text='逗号停顿(秒):',width=15).grid(row=2,column=2)
tk.Label(row1,text='句号次数:',width=15).grid(row=3,column=2)
tk.Label(row1,text='句号停顿(秒)',width=15).grid(row=4,column=2)
tk.Label(row1,text='大段次数',width=15).grid(row=5,column=2)
tk.Label(row1,text='大段停顿(秒)',width=15).grid(row=6,column=2)
tk.Label(row1,text='全部音频次数',width=15).grid(row=7,column=2)
tk.Label(row1,text='是否生成音频',width=15).grid(row=8,column=2) tk.Entry(row1, textvariable=self.B00, width=13).grid(row=1,column=3)
tk.Entry(row1, textvariable=self.B01, width=13).grid(row=2,column=3)
tk.Entry(row1, textvariable=self.B10, width=13).grid(row=3,column=3)
tk.Entry(row1, textvariable=self.B11, width=13).grid(row=4,column=3)
tk.Entry(row1, textvariable=self.B20, width=13).grid(row=5,column=3)
tk.Entry(row1, textvariable=self.B21, width=13).grid(row=6,column=3)
tk.Entry(row1, textvariable=self.B30, width=13).grid(row=7,column=3)
checkB = tk.Checkbutton(row1, text="播放", variable=self.B31)
checkB.select()
checkB.grid(column=3, row=8, sticky=tk.W)
self.A31.set(int(data[7]))
self.B31.set(int(data[15])) tk.Button(row1, text="取消", command=self.cancel, width=13).grid(row=9,column=0)
tk.Button(row1, text="确定", command=self.ok, width=13).grid(row=9,column=3) def ok(self):
self.userinfo_A = [self.A00.get(), self.A01.get(),self.A10.get(),self.A11.get(),self.A20.get(),self.A21.get(),self.A30.get(),self.A31.get()] # 设置数据
self.userinfo_B = [self.B00.get(), self.B01.get(),self.B10.get(),self.B11.get(),self.B20.get(),self.B21.get(),self.B30.get(),self.B31.get()] # 设置数据
# print(self.userinfo)
# print(self.userinfo_A[7])
# print(self.userinfo_B[7])
self.userinfo_A[7] = str(self.userinfo_A[7])
self.userinfo_B[7] = str(self.userinfo_B[7])
data = self.userinfo_A + self.userinfo_B
# print(data)
assist.write_txt_data(data,os.path.dirname(os.path.realpath(__file__))+"\\data_set.txt")
self.destroy() # 销毁窗口
def cancel(self):
self.userinfo = None # 空!
self.destroy() ################################
class main_code(tk.Tk):
def __init__(self):
super().__init__()
self.audio_path = ""
self.run = True
self.vartext = tkinter.StringVar() self.txt='' self.mark_text = '欢迎使用!'
self.insert_text = ''
self.vartext.set(self.mark_text)
self.filename = ""
self.audio_path = ""
self.audio_len = 0
self.data_play = []
self.sound = 0
self.title('音频标记')
self.setupUI() def setupUI(self): row4 = tk.Frame(self)
row4.pack(fill="x") tk.Button(row4,text='导入文本',width=27,command=self.select).grid(row=0,column=0)
tk.Button(row4,text='设置文本',width=27,command=self.setup_config).grid(row=0,column=1)
tk.Button(row4,text='生成文本',width=27,command=self.lay).grid(row=0,column=2) label = tkinter.Label(row4,height=3,textvariable=self.vartext, bg='white', font=('黑体', 10), anchor='w').grid(row=1,column=0,columnspan=3) entry1 = tkinter.Entry(row4,width=85)
entry1.bind('<Key>', self.insert_mark)
entry1.grid(row=2,column=0,columnspan=3)
self.insert_text = entry1.get() def select(self): #获取audio_path和audio_len
self.audio_path = tkinter.filedialog.askopenfilename(initialdir = 'C:\\Users\\Administrator\\Desktop',filetypes=( ("txt or docx files", "*.txt;*.docx"),("All files", "*.*")))
if self.audio_path=="":
self.vartext.set('未导入任何文件')
else:
p,f=os.path.split(self.audio_path)
path = os.path.dirname(os.path.realpath(__file__)) + '\\data\\' + str(os.path.splitext(f)[0])
isExists = os.path.exists(path)
if not isExists: #如果不存在这个目录
os.makedirs(path) #创建一个新的路径
shutil.copyfile(self.audio_path,path+'\\'+f)
if str(os.path.splitext(f)[1])=='.txt':
file_object = open(self.audio_path,'r', encoding='UTF-8')
try:
file_context = file_object.read()
finally:
file_object.close()
self.txt=file_context
self.vartext.set('已导入txt文本')
# print(1)
elif str(os.path.splitext(f)[1])=='.docx':
import docx
document = docx.Document(self.audio_path)
txt=''
for paragraph in document.paragraphs:
txt+=paragraph.text
self.txt=txt
self.vartext.set('已导入docx文本')
self.audio_path=path+'\\'+f#更新数据路径 def insert_mark(self,event): #非主动线程
# while self.run:
# self.insert_text = self.insert_text + event.char
pass
def lay(self):
# txt=entry1.get()
print(self.insert_text)
print(123) '''
self.vartext.set('正在生成文本标记文件')
# data_set = assist.read_txt_data(os.path.dirname(os.path.realpath(__file__))+"\\data_set.txt")
mark_set=[1,1,0,1,1,0,1,1]
import re
txt_comma=re.split(u'。',self.txt[:-1])
p,f=os.path.split(self.audio_path)
# print(p)
# print(f)
for i in range(len(txt_comma)):
txt_comma[i]=txt_comma[i].split(',') # print(txt_comma)
if mark_set[0]==1:
txt_A=''
for i in txt_comma:
txt_A=txt_A+out_comma(i,mark_set[1],mark_set[2])
# print(txt_A)
fobj=open(p+'\\'+str(os.path.splitext(f)[0])+'_A'+str(os.path.splitext(f)[1]),'w')
fobj.write(txt_A)
fobj.close() if mark_set[4]==1:
txt_B=''
for i in txt_comma:
txt_B=txt_B+out_comma(i,mark_set[5],mark_set[6])
# print(txt_B)
fobj=open(p+'\\'+str(os.path.splitext(f)[0])+'_B'+str(os.path.splitext(f)[1]),'w')
fobj.write(txt_B)
fobj.close()
''' def setup_config(self):
res = self.ask_userinfo()
if res is None: return
def ask_userinfo(self):
inputDialog = out_setconfig()
self.wait_window(inputDialog) # 这一句很重要!!! if __name__ == '__main__':
app = main_code()
app.mainloop()

多线程的音频打标记的python实现(原创)的更多相关文章

  1. python 多线程两种实现方式,Python多线程下的&lowbar;strptime问题,

    python 多线程两种实现方式 原创 Linux操作系统 作者:杨奇龙 时间:2014-06-08 20:24:26  44021  0 目前python 提供了几种多线程实现方式 thread,t ...

  2. 失去循环标记的Python,我这样实现跳出外层循环

    不完美的Python 自从各类Python大火,感觉天上地下哪儿都有Python的一席之地,Python功夫好啊-但python有些细节上缺少其他语言的便利.今天我们就来举几个例子. 跳出外层循环 大 ...

  3. 音频数据增强及python实现

    博客作者:凌逆战 博客地址:https://www.cnblogs.com/LXP-Never/p/13404523.html 音频时域波形具有以下特征:音调,响度,质量.我们在进行数据增强时,最好只 ...

  4. python 多线程,tthread模块比较底层,而threading模块是对thread做了一些包装,multithreading

    Python多线程详解 2016/05/10 · 基础知识 · 1 评论· 多线程 分享到:20 本文作者: 伯乐在线 - 王海波 .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 1.多线程的 ...

  5. Python的多线程锁跟队列

    一.互斥锁: 1.线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁. 2.互斥锁为资源引入一个状态:锁定.非锁定 3.某个线程要更改共享数据是,先将其锁定.此时资源的状态为锁定, ...

  6. FFmpeg学习5:多线程播放视音频

    在前面的学习中,视频和音频的播放是分开进行的.这主要是为了学习的方便,经过一段时间的学习,对FFmpeg的也有了一定的了解,本文就介绍了 如何使用多线程同时播放音频和视频(未实现同步),并对前面的学习 ...

  7. Python GIL 多线程机制 (C source code&rpar;

    最近阅读<Python源码剖析>对进程线程的封装解释: GIL,Global Interpreter Lock,对于python的多线程机制非常重要,其如何实现的?代码中实现如下: 指向一 ...

  8. Python 爬取所有51VOA网站的Learn a words文本及mp3音频

    Python 爬取所有51VOA网站的Learn a words文本及mp3音频 #!/usr/bin/env python # -*- coding: utf-8 -*- #Python 爬取所有5 ...

  9. Python标准库08 多线程与同步 &lpar;threading包&rpar;

    Python主要通过标准库中的threading包来实现多线程.在当今网络时代,每个服务器都会接收到大量的请求.服务器可以利用多线程的方式来处理这些请求,以提高对网络端口的读写效率.Python是一种 ...

随机推荐

  1. python Data type conversation

    >>> repr(111.5) '111.5' >>> repr(10) ' >>> int(") 11 >>> lo ...

  2. tp空操作和空控制器处理

    TP框架几个重要文件:index.php,ThinkPHP.php,Library/Think/Think.class.php,Library/Think/App.class.php,conversi ...

  3. 在网页中编辑报表的报表设计器Stimulsoft Reports Designer&period;Web报表控件

    Stimulsoft Reports Designer.Web报表控件是一款网页报表设计器.您想在网页中编辑您的报表吗?现在是可能的! Stimulsoft Reports Designer.Web ...

  4. logstash Codec

    Logstash 使用一个名叫FileWatch的Ruby Gem库来监听文件变化,这个库支持glob扩展文件路径, 而且会记录一个叫.sincedb的数据库文件来跟踪被监听日志文件的当前读取位置,所 ...

  5. 一个fork短码的扩展版本

    原本代码: 链接 int skip = !!fork() + 2*(!!fork()); for (uint32_t i=skip;i!=INT_MAX;i+=4) { } 这个是多进程加速循环的代码 ...

  6. 关于在Python下安装布隆过滤器(bloomfilter)的方法

    由于在爬虫代码中需要实现信息的去重功能,所以需借助bloomfilter,在看完各种博客后发现没有安装,这就尴尬了,不会连门都找不到吧.那就安装呗,各种错误,查看官方文档:http://axiak.g ...

  7. Selenium WebDriver 中鼠标和键盘事件分析及扩展&lbrack;转载&rsqb;

    原文:http://www.ibm.com/developerworks/cn/java/j-lo-keyboard/ 概念 在使用 Selenium WebDriver 做自动化测试的时候,会经常模 ...

  8. FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-TU

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  9. Android stdio 报错 error invoking main method

    打开Android stdio失败 报错:error invoking main method 想想前一天做了什么事?? 昨天把企图把Android Stdio文件包移盘,但是中途截止了,也就是说移动 ...

  10. 如何利用 Visual Studio 自定义项目或工程模板&lpar;转载&rpar;

    在开发项目的时候,由其是商业性质的大型项目时,往往需要在每个代码文件上都加上一段关于版权.开发人员的信息,并且名称空间上都需要带有公司的标志.这个时候,是选择在开发的时候手动添加还是自动生成呢? 我们 ...