使用Python編寫(xiě)錄屏錄音工具
1.簡(jiǎn)介
工具界面十分簡(jiǎn)單,默認(rèn)是全屏錄屏錄音(第一次使用得手動(dòng)開(kāi)啟電腦聲音設(shè)置的立體聲混音作為輸入),勾選不錄制揚(yáng)聲器系統(tǒng)聲音后只錄屏,如果想自定義區(qū)域錄制要先選擇自定義區(qū)域錄屏,然后再點(diǎn)擊開(kāi)始錄制即可。
2.運(yùn)行界面
可勾不錄制揚(yáng)聲器系統(tǒng)聲音
選擇錄制區(qū)域再點(diǎn)擊開(kāi)始錄制
3.相關(guān)源碼
import tkinter as tk from tkinter import ttk import tkinter.messagebox as messagebox import pyautogui import cv2 import numpy as np from datetime import datetime import threading import pyaudio import wave import os from moviepy.editor import VideoFileClip, AudioFileClip # 隱藏命令行 import win32console import win32gui win = win32console.GetConsoleWindow() win32gui.ShowWindow(win, 0) class Popup(tk.Tk): def __init__(self): super().__init__() self.title("設(shè)置") self.geometry("300x250") self.configure(bg="#333333") self.create_widgets() self.recording_area = None # 初始化錄制區(qū)域 self.record_microphone = True # 初始化打開(kāi)麥克風(fēng) def create_widgets(self): self.recording = False self.stop_event = threading.Event() # 使用 Event 對(duì)象 self.rec_button = tk.Button(self, text="開(kāi)始錄制", command=self.toggle_recording, bg="#333333", fg="white", borderwidth=2, relief="solid") self.rec_button.pack(pady=10) self.stop_button = tk.Button(self, text="停止錄制", command=self.stop_recording, bg="#333333", fg="white", borderwidth=2, relief="solid", state=tk.DISABLED) self.stop_button.pack(pady=5) # 區(qū)域選擇按鈕 self.select_area_button = tk.Button(self, text="選擇錄制區(qū)域", command=self.select_area, bg="#333333", fg="white", borderwidth=2, relief="solid") self.select_area_button.pack(pady=10) # 揚(yáng)聲器錄制選項(xiàng) self.mic_checkbox = tk.Checkbutton(self, text="不錄制揚(yáng)聲器系統(tǒng)聲音", command=self.toggle_microphone, bg="#333333", fg="white", selectcolor="black") self.mic_checkbox.pack(pady=10) def toggle_microphone(self): # 切換麥克風(fēng)錄制的狀態(tài) self.record_microphone = not self.record_microphone def select_area(self): # 打開(kāi)一個(gè)全屏窗口,允許用戶(hù)通過(guò)鼠標(biāo)拖動(dòng)選擇區(qū)域 self.selection_window = tk.Toplevel(self) self.selection_window.attributes('-fullscreen', True) self.selection_window.attributes('-alpha', 0.3) # 半透明 self.selection_window.config(bg="gray") self.canvas = tk.Canvas(self.selection_window, cursor="cross", bg="gray") self.canvas.pack(fill="both", expand=True) self.rect_id = None self.start_x = None self.start_y = None # 綁定鼠標(biāo)事件 self.canvas.bind("<ButtonPress-1>", self.on_mouse_down) self.canvas.bind("<B1-Motion>", self.on_mouse_drag) self.canvas.bind("<ButtonRelease-1>", self.on_mouse_up) def on_mouse_down(self, event): # 記錄起點(diǎn) self.start_x = event.x self.start_y = event.y self.rect_id = self.canvas.create_rectangle(self.start_x, self.start_y, self.start_x, self.start_y, outline='red', width=2) def on_mouse_drag(self, event): # 動(dòng)態(tài)更新矩形 self.canvas.coords(self.rect_id, self.start_x, self.start_y, event.x, event.y) def on_mouse_up(self, event): # 記錄終點(diǎn)并計(jì)算區(qū)域 end_x = event.x end_y = event.y self.recording_area = (self.start_x, self.start_y, end_x - self.start_x, end_y - self.start_y) self.selection_window.destroy() messagebox.showinfo("信息", f"選擇的錄制區(qū)域?yàn)椋簕self.recording_area}") def toggle_recording(self): if not self.recording: self.start_recording() else: self.stop_recording() def start_recording(self): self.recording = True self.stop_event.clear() # 清除事件狀態(tài) frame_rate = 30 timestamp = self.get_current_timestamp() self.video_filename = f"recorded_video_{timestamp}.mp4" self.audio_filename = f"recorded_audio_{timestamp}.wav" if self.recording_area is None: screen_width, screen_height = pyautogui.size() self.recording_area = (0, 0, screen_width, screen_height) # 默認(rèn)全屏 codec = cv2.VideoWriter_fourcc(*"mp4v") self.video_out = cv2.VideoWriter(self.video_filename, codec, frame_rate, (self.recording_area[2], self.recording_area[3])) # 判斷是否需要錄制麥克風(fēng) if self.record_microphone: # 聲音錄制線(xiàn)程 self.audio_thread = threading.Thread(target=self.record_audio, args=(self.audio_filename,)) self.audio_thread.start() # 啟動(dòng)錄制線(xiàn)程 self.recording_thread = threading.Thread(target=self.record_screen) self.recording_thread.start() self.rec_button.config(text="正在錄制", state=tk.DISABLED) self.stop_button.config(state=tk.NORMAL) def record_screen(self): while not self.stop_event.is_set(): # 檢查事件狀態(tài) img = pyautogui.screenshot(region=self.recording_area) # 錄制自定義區(qū)域 frame = np.array(img) frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR) self.video_out.write(frame) self.video_out.release() print("視頻錄制結(jié)束") def record_audio(self, filename): chunk = 1024 sample_format = pyaudio.paInt16 channels = 2 fs = 44100 # 采樣頻率 p = pyaudio.PyAudio() # 打開(kāi)麥克風(fēng)輸入流 stream = p.open(format=sample_format, channels=channels, rate=fs, input=True, frames_per_buffer=chunk) frames = [] while not self.stop_event.is_set(): # 檢查事件狀態(tài) data = stream.read(chunk) frames.append(data) stream.stop_stream() stream.close() p.terminate() # 保存音頻到 wav 文件 with wave.open(filename, 'wb') as wf: wf.setnchannels(channels) wf.setsampwidth(p.get_sample_size(sample_format)) wf.setframerate(fs) wf.writeframes(b''.join(frames)) print("錄音結(jié)束") def stop_recording(self): self.recording = False self.stop_event.set() # 設(shè)定事件,結(jié)束錄制 if self.record_microphone: self.audio_thread.join() # 等待音頻線(xiàn)程結(jié)束 if os.path.isfile('merged_video.mp4'): messagebox.showinfo("提示", "合并視頻文件已保存至當(dāng)前目錄文件夾,想重新錄制請(qǐng)刪除原文件后重試!") # 更新按鈕狀態(tài) self.rec_button.config(text="請(qǐng)刪除原文件后再開(kāi)始錄制", state=tk.NORMAL) self.stop_button.config(state=tk.DISABLED) else: # 合成音視頻 self.merge_audio_video() def merge_audio_video(self): merge_file = 'merged_video.mp4' video_clip = VideoFileClip(self.video_filename) if self.record_microphone: audio_clip = AudioFileClip(self.audio_filename) final_clip = video_clip.set_audio(audio_clip) else: final_clip = video_clip # 如果沒(méi)有錄音,只保存視頻 final_clip.write_videofile(merge_file, codec='libx264', audio_codec="aac") # 刪除錄制的視頻文件和音頻文件 os.remove(self.video_filename) if self.record_microphone: os.remove(self.audio_filename) print("音視頻合成完成,存儲(chǔ)為", merge_file) # 更新按鈕狀態(tài) self.rec_button.config(text="開(kāi)始錄制", state=tk.NORMAL) self.stop_button.config(state=tk.DISABLED) def get_current_timestamp(self): return datetime.now().strftime("%Y%m%d_%H%M%S") if __name__ == "__main__": popup = Popup() popup.mainloop()
以上就是使用Python編寫(xiě)錄屏錄音工具的詳細(xì)內(nèi)容,更多關(guān)于Python錄屏錄音的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python實(shí)現(xiàn)將內(nèi)容寫(xiě)入文件的五種方法總結(jié)
本篇帶你詳細(xì)看一下python將內(nèi)容寫(xiě)入文件的方法以及細(xì)節(jié),主要包括write()方法、writelines()?方法、print()?函數(shù)、使用?csv?模塊、使用?json?模塊,需要的可以參考一下2023-04-04編寫(xiě)Python腳本使得web頁(yè)面上的代碼高亮顯示
這篇文章主要介紹了編寫(xiě)Python腳本使得web頁(yè)面上的代碼高亮顯示,主要使用了pygments工具,需要的朋友可以參考下2015-04-04python中的Numpy二維數(shù)組遍歷與二維數(shù)組切片后遍歷效率比較
這篇文章主要介紹了python中的Numpy二維數(shù)組遍歷與二維數(shù)組切片后遍歷效率比較,在python-numpy使用中,可以用雙層?for循環(huán)對(duì)數(shù)組元素進(jìn)行訪(fǎng)問(wèn),也可以切片成每一行后進(jìn)行一維數(shù)組的遍歷,下面小編擊來(lái)舉例介紹吧,需要的朋友可以參考一下2022-03-03Python實(shí)現(xiàn)一個(gè)帶權(quán)無(wú)回置隨機(jī)抽選函數(shù)的方法
這篇文章主要介紹了Python實(shí)現(xiàn)一個(gè)帶權(quán)無(wú)回置隨機(jī)抽選函數(shù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07基于Python實(shí)現(xiàn)人臉識(shí)別相似度對(duì)比功能
人臉識(shí)別技術(shù)是一種通過(guò)計(jì)算機(jī)對(duì)人臉圖像進(jìn)行分析和處理,從而實(shí)現(xiàn)自動(dòng)識(shí)別和辨認(rèn)人臉的技術(shù),隨著計(jì)算機(jī)視覺(jué)和模式識(shí)別領(lǐng)域的快速發(fā)展,人臉識(shí)別技術(shù)取得了長(zhǎng)足的進(jìn)步,本文給大家介紹了基于Python實(shí)現(xiàn)人臉識(shí)別相似度對(duì)比功能,感興趣的朋友可以參考下2024-01-01