本帖最后由 dltest 于 2022-10-15 10:20 编辑
区别于之前我发的贴子,本程序需要你,提前获得直播流地址,将此地址复制到框内,再输入主播名用于创建保存文件夹。
程序运行后会自动保存本次输入框内数据,方便下次开启软件直接加载
开始录制后,屏幕会出现一个黑框,是本程序调用ffmpeg.exe,关闭黑框,录制进程也会关屏
打包后的程序如下: 同样,本程序同时打包了ffmpeg.exe,所以包比较大
https://wwz.lanzoub.com/ibgJd0dw58uj
密码:52pj
代码如下
[Python] 纯文本查看 复制代码
# -*- coding:utf-8 -*-#@FileName :m3u_flv_2_ts.py# @ Author :dltest@52pojieimport configparserimport datetimeimport osimport subprocessimport threadingimport timeimport tkinter as tkimport tkinter.font as tkFontthd = set()LOG_LINE_NUM =0class App: def __init__(self, root): self.editdate = '2022/10/15' self.initUI(root) self.initData() def initData(self): self.tag = 'odd' self.count = 0 self.dir = '' self.flag = True if not os.path.exists('ZBconfig.ini'): f = open("ZBconfig.ini",'w', encoding='utf-8-sig') f.close() self._log("创建配置文件") else: self._log("加载配置文件") zhubo_address,zhubo_name= self.getzhubo() if zhubo_address: self._log(f'加载地址【{zhubo_address}】') self._log(f'加载主播名【{zhubo_name}】') self.GLineEdit_492.insert(0,zhubo_address) self.GLineEdit_956.insert(0,zhubo_name) else: self._log('请输入直播间地址') def getzhubo(self): try: config = configparser.ConfigParser() config.read('ZBconfig.ini', encoding='utf-8-sig') zhubo_address=config.get('1', '直播地址') zhubo_name=config.get('1', '主播名') return zhubo_address,zhubo_name except: pass return None,None def initUI(self,root): #setting title root.title(f"直播流录制 {self.editdate} dltest@52pojie") #setting window size width=770 height=383 screenwidth = root.winfo_screenwidth() screenheight = root.winfo_screenheight() alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2) root.geometry(alignstr) root.resizable(width=False, height=False) self.GLabel_597=tk.Label(root) ft = tkFont.Font(family='Times',size=10) self.GLabel_597["font"] = ft self.GLabel_597["fg"] = "#333333" self.GLabel_597["justify"] = "center" self.GLabel_597["text"] = "直播地址" self.GLabel_597.place(x=0,y=10,width=61,height=30) self.GLineEdit_492=tk.Entry(root) self.GLineEdit_492["borderwidth"] = "1px" ft = tkFont.Font(family='Times',size=10) self.GLineEdit_492["font"] = ft self.GLineEdit_492["fg"] = "#333333" self.GLineEdit_492["justify"] = "center" self.GLineEdit_492["text"] = "httpurl" self.GLineEdit_492.place(x=60,y=10,width=309,height=30) self.GLineEdit_956=tk.Entry(root) self.GLineEdit_956["borderwidth"] = "1px" ft = tkFont.Font(family='Times',size=10) self.GLineEdit_956["font"] = ft self.GLineEdit_956["fg"] = "#333333" self.GLineEdit_956["justify"] = "center" self.GLineEdit_956["text"] = "zhoboname" self.GLineEdit_956.place(x=440,y=10,width=81,height=30) self.GLabel_603=tk.Label(root) ft = tkFont.Font(family='Times',size=10) self.GLabel_603["font"] = ft self.GLabel_603["fg"] = "#333333" self.GLabel_603["justify"] = "center" self.GLabel_603["text"] = "主播名" self.GLabel_603.place(x=380,y=10,width=47,height=30) self.GButton_316=tk.Button(root) self.GButton_316["bg"] = "#efefef" ft = tkFont.Font(family='Times',size=10) self.GButton_316["font"] = ft self.GButton_316["fg"] = "#000000" self.GButton_316["justify"] = "center" self.GButton_316["text"] = "开始" self.GButton_316.place(x=530,y=10,width=72,height=30) self.GButton_316["command"] = self.GButton_316_command self.GButton_35=tk.Button(root) self.GButton_35["bg"] = "#efefef" ft = tkFont.Font(family='Times',size=10) self.GButton_35["font"] = ft self.GButton_35["fg"] = "#000000" self.GButton_35["justify"] = "center" self.GButton_35["text"] = "停止" self.GButton_35.place(x=610,y=10,width=71,height=30) self.GButton_35["command"] = self.GButton_35_command self.GButton_610=tk.Button(root) self.GButton_610["bg"] = "#efefef" ft = tkFont.Font(family='Times',size=10) self.GButton_610["font"] = ft self.GButton_610["fg"] = "#000000" self.GButton_610["justify"] = "center" self.GButton_610["text"] = "打开" self.GButton_610.place(x=690,y=10,width=73,height=30) self.GButton_610["command"] = self.GButton_610_command self.GLineEdit_50=tk.Text(root) self.GLineEdit_50["borderwidth"] = "1px" ft = tkFont.Font(family='Times',size=10) self.GLineEdit_50["font"] = ft self.GLineEdit_50["fg"] = "#333333" self.GLineEdit_50.place(x=10,y=50,width=751,height=323) def GButton_316_command(self): #开始 now = time.strftime("%Y-%m-%d-%H-%M-%S",time.localtime(time.time())) zhubo = self.GLineEdit_956.get() if len(zhubo) < 1: zhubo = '未命名' if not os.path.exists(zhubo): os.makedirs('./'+zhubo) self.dir =os.getcwd() + '' + zhubo filename=zhubo + '_' + now + ".ts" ffmpeg_path = "ffmpeg" file = os.getcwd() + '' +zhubo +''+ filename self._log(f'保存路径{file}') start = datetime.datetime.now() hls_pull_url = self.GLineEdit_492.get() if len(hls_pull_url) <1: self._log(f'未输入直播地址') return self._log(f'直播地址:{hls_pull_url}') self._log(f'--------开始录制-----------') self.download(ffmpeg_path,hls_pull_url,file) self.flag = True config = configparser.ConfigParser() config.read('ZBconfig.ini', encoding='utf-8-sig') listx = config.sections()# 获取到配置文件中所有分组名称 if '1' not in listx:# 如果分组type不存在则插入type分组 config.add_section('1') config.set('1', '直播地址', hls_pull_url)# 给type分组设置值 config.set('1', '主播名', zhubo)# 给type分组设置值 o = open('ZBconfig.ini', 'w',encoding='utf-8-sig') config.write(o) o.close()#不要忘记关闭 obj1 = threading.Thread(target=self.displayinfo, args=({start,zhubo})) obj1.setDaemon(True) obj1.start() def GButton_35_command(self): #停止 self.flag = False global thd for i in thd: i.stdin.write('q'.encode("GBK")) i.communicate() thd.clear() def GButton_610_command(self): #打开 path = self.dir if path: self.open_fp(path) else: path =os.getcwd() + '未命名' self.open_fp(path) def open_fp(self, fp): import platform systemType: str = platform.platform() # 获取系统类型 if 'mac' in systemType: # 判断以下当前系统类型 fp: str = fp.replace("", "/") # mac系统下,遇到``让路径打不开,不清楚为什么哈,觉得没必要的话自己可以删掉啦,18行那条也是 subprocess.call(["open", fp]) else: fp: str = fp.replace("/", "") # win系统下,有时`/`让路径打不开 try: os.startfile(fp) except: self._log(f'{"-" * 20}文件还未{"-" * 20}') def download(self,ffmpeg_path,hls_pull_url,file): try: _output = subprocess.Popen([ ffmpeg_path, "-y", "-v","verbose", "-rw_timeout","10000000", # 10s "-loglevel","error", "-hide_banner", # "-user_agent",headers["User-Agent"], "-analyzeduration","2147483647", "-probesize","2147483647", "-i",hls_pull_url, '-bufsize','5000k', "-map","0", "-sn","-dn", "-f","mpegts", # "-bsf:v","h264_mp4toannexb", # "-c","copy", "-c:v","copy", '-max_muxing_queue_size','64', "{path}".format(path=file), ], stderr = subprocess.STDOUT,stdin=subprocess.PIPE) except subprocess.CalledProcessError as exc: print(str(exc.output) +" 发生错误的行数: "+str(exc.__traceback__.tb_lineno) ) self.flag = False global thd thd.add(_output) def displayinfo(self,start:datetime.datetime,zhubo): start1 = datetime.datetime.now() time.sleep(10) while self.flag: time.sleep(30) self._log('循环值守录制抖音直播') # self._log("x"*60) end = datetime.datetime.now() self._log(f"{zhubo} 正在录制中") self._log('总共录制时间: ' +str(end - start1)) self._log("x"*60) return def _log(self, logmsg): # logmsg = logmsg[:25] if len(logmsg) > 25 else logmsg global LOG_LINE_NUM current_time = self.get_current_time() logmsg_in = str(current_time) + " " +str(logmsg) + "n" # 换行 self.GLineEdit_50.tag_config("even", background='#e0e0e0') self.GLineEdit_50.tag_config("odd", background='#ffffff') self.tag = 'odd' if self.tag == 'even' else 'even' if LOG_LINE_NUM <= 20: self.GLineEdit_50.insert('end', logmsg_in, self.tag) LOG_LINE_NUM = LOG_LINE_NUM + 1 else: self.GLineEdit_50.delete(1.0, 2.0) self.GLineEdit_50.insert('end', logmsg_in, self.tag) def get_current_time(self): current_time = time.strftime('%H:%M:%S', time.localtime(time.time())) return current_timedef on_closing() : global thd if len(thd)>0: for i in thd: i.stdin.write('q'.encode("GBK")) i.communicate() print ("Window closed") root.destroy()if __name__ == "__main__": root = tk.Tk() app = App(root) root.protocol("WM_DELETE_WINDOW", on_closing) root.mainloop()