当前位置:首页>PPT>封神!PPT一键转数字人视频工具v4.0

封神!PPT一键转数字人视频工具v4.0

  • 2026-05-02 02:23:14
封神!PPT一键转数字人视频工具v4.0

零门槛搞定专业级输出

在这个可视化表达为王的时代,PPT转视频早已不是“加分项”,而是职场人、自媒体人、培训师的“必备技能”——无论是做产品宣讲、线上课程、企业汇报,还是短视频内容,把静态PPT变成带语音、带数字人的动态视频,都能让内容更有吸引力、传播力。但市面上大多数工具要么收费高昂,要么操作繁琐,要么存在致命bug:音画不同步、PPT页面导出错乱、渲染速度慢、预览功能鸡肋,甚至导出后结尾出现重复帧,严重影响使用体验。

今天,就给大家带来一款「封神级」PPT智能转数字人视频工具v4.0(修复版),彻底解决所有痛点!这款工具基于Python开发,搭载PyQt5可视化界面,美观大方、功能全面、操作简单,无需专业编程基础,小白也能一键上手;支持PPT转图片、语音自动生成、数字人叠加、多模式预览(3页快速预览/20秒片段预览)、极速渲染,更修复了旧版7大核心bug,实现音画100%同步、无残留文件、结尾无重复帧,输出效果精致高级,完全满足专业场景需求。

不管你是需要快速制作培训课件、企业宣传视频,还是自媒体短视频、汇报演示视频,这款工具都能帮你节省80%的时间,告别手动剪辑、语音录制的繁琐流程,一键实现“PPT导入→参数设置→生成视频”的全流程自动化,让每一份PPT都能轻松变身专业级动态视频,兼顾颜值与实用性,再也不用为“PPT转视频”发愁!

一、工具核心亮点(精致高级,功能拉满)

在详解代码之前,先带大家快速了解这款工具的核心优势,为什么能称之为“零门槛专业级工具”:

  • 可视化界面,颜值与实用性双在线:采用PyQt5搭建,布局清晰、样式精致,按钮、输入框、进度条设计美观,支持数字人预览,整体界面不透明、不杂乱,操作逻辑简单,无需记忆任何命令,点击按钮就能完成所有操作。

  • 功能全面,覆盖全场景需求:支持PPT文本提取、PPT转高清图片(1920*1080)、edge-tts智能语音生成(支持多种中文发音人、语速调节)、数字人叠加(透明底PNG适配)、多模式预览、极速渲染,还支持暂停/停止操作,灵活控制生成过程。

  • bug全修复,体验更流畅:针对旧版音画错位、残留文件污染、结尾重复帧、预览模式异常等7大问题,进行全面修复,实现音画严格对齐、无残留文件、渲染极速稳定,输出视频清晰无瑕疵。

  • 零门槛上手,极速渲染:无需专业编程基础,无需安装复杂插件,一键选择PPT、设置参数,即可生成视频;支持FFmpeg极速渲染,多种编码速度可选,最快模式下,几分钟就能完成多页PPT转视频。

二、代码核心模块详解(3大模块,读懂底层逻辑)

这款工具的代码结构清晰,核心分为3大模块,每个模块各司其职、相互配合,既保证了功能的完整性,又兼顾了运行的稳定性,下面我们逐模块详细解析,就算是编程新手也能轻松理解。

模块1:界面搭建(PyQt5)—— 美观精致,操作友好

界面是工具的“门面”,也是用户交互的核心,该模块基于PyQt5搭建,实现了所有可视化功能,包括文件选择、参数设置、按钮控制、日志显示、进度反馈等,整体设计遵循“美观、简洁、易用”的原则。

核心亮点:采用分组布局(文件选择、参数设置),结构清晰;添加样式美化,按钮、输入框、进度条均有圆角设计,颜色搭配舒适,避免杂乱;支持数字人预览,选择图片后可实时显示效果;日志实时输出,操作过程可追溯;进度条实时反馈,让用户清晰了解生成进度。

关键代码解析:

  • MainWindow类:继承QMainWindow,是整个界面的核心,负责初始化界面布局、加载样式、绑定按钮事件。

  • init_ui方法:搭建界面布局,包括标题栏、文件选择区(PPT选择、数字人选择)、参数设置区(发音人、语速、编码速度)、按钮控制区(预览、生成、暂停、停止)、进度条、日志显示区。

  • apply_styles方法:设置界面样式,包括窗口背景、分组框、输入框、按钮、进度条的样式,保证界面精致高级、不透明。

  • choose_ppt/choose_avatar方法:实现文件选择功能,支持PPT(.pptx)和数字人图片(.png/.jpg)的选择,并实时预览数字人图片。

模块2:核心功能实现—— 音画同步,极速渲染

这是工具的“核心灵魂”,负责实现PPT转视频的全流程逻辑,包括PPT文本提取、PPT转图片、语音生成、视频合成,也是修复旧版bug的重点模块,确保音画同步、无残留、无异常。

核心亮点:修复7大bug(清空旧输出文件、按文本页数导出图片、预览模式音画绑定、图片与音频数量校验、20秒预览按页面截取、结尾无重复帧、静音页处理);支持多模式预览(3页快速预览、20秒片段预览);语音生成支持无文本页静音处理;视频合成支持数字人叠加,可调节数字人大小和位置。

关键代码解析:

  • WorkerThread类:继承QThread,负责后台执行耗时操作(PPT处理、语音生成、视频合成),避免阻塞界面,实现多线程同步。

  • extract_text方法:提取PPT文本(优先提取备注文本,无备注则提取页面文本),为语音生成提供素材,确保语音与PPT内容对应。

  • ppt_to_png方法:将PPT按文本页数导出为高清PNG图片(1920*1080),严格匹配文本页数,避免音画错位,支持预览模式下的页数限制。

  • generate_tts方法:基于edge-tts生成语音,支持选择发音人、调节语速,无文本页自动生成静音,语音生成失败时自动降级为静音,保证流程不中断。

  • compose_video_ffmpeg方法:核心视频合成方法,调用FFmpeg实现图片、语音的合成,支持数字人叠加,修复结尾重复帧问题,实现极速渲染,多种编码速度可选。

模块3:线程管理与状态控制—— 灵活可控,稳定运行

该模块负责管理后台线程,实现暂停、停止、进度反馈等功能,确保工具运行稳定,用户可灵活控制生成过程,避免因误操作或需求变更导致的流程中断。

核心亮点:采用QMutex和QWaitCondition实现线程的暂停/唤醒,避免线程冲突;实时发送日志信号、进度信号,让用户清晰了解操作状态;任务停止时自动清理资源,避免内存泄漏;任务完成后弹出提示,告知用户生成结果和文件路径。

关键代码解析:

  • toggle_pause方法:实现线程的暂停/唤醒,点击暂停按钮时,线程进入等待状态,点击继续时,线程恢复运行。

  • stop方法:停止线程运行,清理线程资源,终止当前任务,避免资源浪费。

  • check_state方法:检查线程状态,若任务被停止则抛出异常,若任务被暂停则进入等待状态,确保线程运行安全。

  • 信号绑定:WorkerThread类通过log_signal、progress_signal、finished_signal等信号,与MainWindow类实现通信,实时更新日志、进度和任务状态。

三、完整代码(可直接复制运行)

以下是工具的完整代码,已修复所有已知bug,可直接复制到Python环境中运行,只需安装对应依赖,即可实现所有功能,建议收藏备用!

import sysimport osimport asyncioimport edge_ttsimport subprocessimport shutilfrom win32com.client import Dispatchfrom pptx import Presentationfrom moviepy.editor import AudioFileClip, AudioClip, concatenate_audioclipsfrom PyQt5.QtWidgets import (    QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,    QPushButton, QLabel, QLineEdit, QComboBox, QTextEdit,    QFileDialog, QMessageBox, QProgressBar, QGroupBox)from PyQt5.QtCore import QThread, pyqtSignal, Qt, QMutex, QWaitConditionfrom PyQt5.QtGui import QFont, QPixmapdefget_ffmpeg_path():try:import imageio_ffmpegreturn imageio_ffmpeg.get_ffmpeg_exe()except ImportError:passtry:        subprocess.run(["ffmpeg""-version"], capture_output=True)return"ffmpeg"except FileNotFoundError:returnNoneclassWorkerThread(QThread):    log_signal = pyqtSignal(str)    progress_signal = pyqtSignal(int)    finished_signal = pyqtSignal(str)    paused_signal = pyqtSignal(bool)def__init__(self, ppt_path, avatar_path, voice, rate, preset, output_folder, ffmpeg_exe, mode='full'):        super().__init__()        self.ppt_path = ppt_path        self.avatar_path = avatar_path        self.voice = voice        self.rate = rate        self.preset = preset        self.output_folder = output_folder        self.ffmpeg_exe = ffmpeg_exe        self.mode = mode         self.img_folder = os.path.join(output_folder, "slides")        self.audio_folder = os.path.join(output_folder, "audio")        self.mutex = QMutex()        self.wait_condition = QWaitCondition()        self.is_paused = False        self.is_stopped = Falsedeftoggle_pause(self):        self.mutex.lock()        self.is_paused = not self.is_paused        self.mutex.unlock()ifnot self.is_paused:            self.wait_condition.wakeAll()        self.paused_signal.emit(self.is_paused)defstop(self):        self.mutex.lock()        self.is_stopped = True        self.is_paused = False        self.mutex.unlock()        self.wait_condition.wakeAll()defcheck_state(self):        self.mutex.lock()if self.is_stopped:            self.mutex.unlock()raise InterruptedError("任务已手动停止")while self.is_paused andnot self.is_stopped:            self.wait_condition.wait(self.mutex)        self.mutex.unlock()defrun(self):try:# 修复1:清空旧输出,杜绝残留文件污染if os.path.exists(self.output_folder):                shutil.rmtree(self.output_folder)            self.init_folders()            self.check_state()            self.log("正在提取PPT文本...")            texts = self.extract_text()            self.check_state()            self.progress_signal.emit(10)            self.log("正在转换PPT为图片...")# 修复2:按文本页数导出图片,保证顺序/数量完全一致            total_slides = self.ppt_to_png(len(texts))            self.check_state()            self.progress_signal.emit(25)# 修复3:统一处理预览模式,音画强绑定            target_texts = texts.copy()if self.mode == 'preview_3':                target_texts = texts[:3]                self.log(f"📌 预览模式:仅处理前{len(target_texts)}页")elif self.mode == 'preview_20s':                self.log(f"📌 预览模式:生成前20秒视频(页面级同步)")            self.log("正在生成语音...")            audio_files, durations = asyncio.run(self.generate_tts(target_texts))            self.check_state()            self.progress_signal.emit(50)            self.log("正在极速合成视频 (纯FFmpeg模式)...")            final_video_path = self.compose_video_ffmpeg(target_texts, audio_files, durations)            self.check_state()            self.progress_signal.emit(100)            self.finished_signal.emit(f"✅ 视频生成完成!\n路径:{final_video_path}")except InterruptedError:            self.log_signal.emit("⚠️ 任务已手动停止")            self.finished_signal.emit("任务已终止")except Exception as e:            self.log_signal.emit(f"❌ 错误:{str(e)}")import traceback            self.log_signal.emit(traceback.format_exc())definit_folders(self):for f in [self.output_folder, self.img_folder, self.audio_folder]:ifnot os.path.exists(f):                os.makedirs(f)deflog(self, msg):        self.log_signal.emit(msg)# 修复4:严格按文本页数导出图片,索引100%对齐defppt_to_png(self, total_text_slides):        powerpoint = Dispatch("PowerPoint.Application")        powerpoint.Visible = Truetry:            pres = powerpoint.Presentations.Open(os.path.abspath(self.ppt_path))            max_slide = min(pres.Slides.Count, total_text_slides)if self.mode == 'preview_3':                max_slide = min(3, max_slide)for i in range(max_slide):                self.check_state()                slide = pres.Slides[i+1]                img_path = os.path.join(self.img_folder, f"slide_{i + 1:03d}.png")                slide.Export(img_path, "PNG"19201080)                self.log(f"✅ 转换第 {i + 1}/{max_slide} 页")            pres.Close()return max_slidefinally:            powerpoint.Quit()defextract_text(self):        prs = Presentation(self.ppt_path)        texts = []for slide in prs.slides:            self.check_state()            txt = ""if slide.has_notes_slide:for shape in slide.notes_slide.shapes:if shape.has_text_frame:                        txt += shape.text_frame.text + " "ifnot txt.strip():for shape in slide.shapes:if shape.has_text_frame:                        txt += shape.text_frame.text + " "            clean = " ".join([t.strip() for t in txt.split() if t.strip()])            texts.append(clean)return textsasyncdefgenerate_tts(self, texts):        files = []        durations = []        total = len(texts)# 无文本页默认时长(可修改)        SILENCE_DURATION = 2.0for i, txt in enumerate(texts):            self.check_state()            path = os.path.join(self.audio_folder, f"audio_{i + 1:03d}.mp3")            files.append(path)ifnot txt.strip():                self.log(f"ℹ️ 第{i + 1}页无文本,生成静音")                self.create_silence_audio(path, SILENCE_DURATION)                durations.append(SILENCE_DURATION)else:try:                    comm = edge_tts.Communicate(txt, self.voice, rate=self.rate)await comm.save(path)                    audio = AudioFileClip(path)                    durations.append(audio.duration)                    audio.close()                    self.log(f"✅ 语音第 {i + 1}/{len(texts)} 条")except Exception as e:                    self.log(f"⚠️ 第{i+1}页语音生成失败,使用静音")                    self.create_silence_audio(path, SILENCE_DURATION)                    durations.append(SILENCE_DURATION)            prog = 25 + int((i + 1) / total * 25)            self.progress_signal.emit(prog)return files, durationsdefcreate_silence_audio(self, filepath, duration=2):defsilent_frame(t):return0        ac = AudioClip(silent_frame, duration=duration)        ac.write_audiofile(filepath, fps=22050, logger=None)        ac.close()# 修复5:核心合成函数,解决20秒预览、数量校验、重复帧defcompose_video_ffmpeg(self, texts, audio_files, durations):        out_name = "output_video.mp4"if self.mode == 'preview_3':            out_name = "preview_3slides_video.mp4"elif self.mode == 'preview_20s':            out_name = "preview_20s_video.mp4"        out = os.path.join(self.output_folder, out_name)        concat_file = os.path.join(self.output_folder, "ffmpeg_concat.txt")# 读取图片,严格匹配音频数量        images = sorted([            os.path.join(self.img_folder, f) for f in os.listdir(self.img_folder) if f.endswith(".png")        ])        process_count = len(audio_files)        images = images[:process_count]        durations = durations[:process_count]# 强制校验:图片=音频,从根源避免错位if len(images) != len(audio_files):raise Exception(f"音画不匹配!图片={len(images)}张,音频={len(audio_files)}条")        target_duration = 20.0if self.mode == 'preview_20s'elseNone        self.check_state()        self.log("正在合并音频轨道...")        final_audio = os.path.join(self.output_folder, "final_audio.mp3")        clips = [AudioFileClip(a) for a in audio_files]# 修复6:20秒模式按完整页面截取,不裁剪音频(音画100%同步)if target_duration:            accumulated_time = 0.0            keep_clips = []            keep_indices = []for idx, dur in enumerate(durations):if accumulated_time + dur > target_duration and keep_clips:break                keep_clips.append(clips[idx])                keep_indices.append(idx)                accumulated_time += dur            clips = keep_clips            images = [images[i] for i in keep_indices]            durations = [durations[i] for i in keep_indices]        final_clip = concatenate_audioclips(clips)        final_clip.write_audiofile(final_audio, logger=None)for c in clips: c.close()        self.check_state()        self.progress_signal.emit(60)        self.log("正在生成 FFmpeg 控制脚本...")# 修复7:删除FFmpeg重复最后一帧,彻底解决结尾偏移with open(concat_file, 'w', encoding='utf-8'as f:for img, dur in zip(images, durations):                abs_path = os.path.abspath(img).replace('\\''/')                f.write(f"file '{abs_path}'\n")                f.write(f"duration {dur}\n")        self.check_state()        self.progress_signal.emit(70)        self.log("正在调用 FFmpeg 极速渲染...")        cmd = [            self.ffmpeg_exe, "-y","-f""concat","-safe""0","-r""24","-i", concat_file,"-i", final_audio        ]        input_map = ["-map""0:v""-map""1:a"]        has_avatar = self.avatar_path and os.path.exists(self.avatar_path)if has_avatar:            avatar_path = os.path.abspath(self.avatar_path).replace('\\''/')            cmd.insert(-2"-i")            cmd.insert(-2, avatar_path)            filter_complex = (f"[2:v]scale=-1:ih*0.35[ava];"f"[0:v][ava]overlay=W-w-10:H-h-10[v]"            )            input_map = ["-filter_complex", filter_complex, "-map""[v]""-map""1:a"]        cmd += input_map        cmd += ["-c:v""libx264","-preset", self.preset,"-crf""23","-pix_fmt""yuv420p","-c:a""aac","-shortest","-threads""auto"        ]        startupinfo = Noneif os.name == 'nt':            startupinfo = subprocess.STARTUPINFO()            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW        self.progress_signal.emit(90)        subprocess.run(            cmd,            stdout=subprocess.DEVNULL,            stderr=subprocess.DEVNULL,            startupinfo=startupinfo        )        self.progress_signal.emit(98)# 清理临时文件try:            os.remove(concat_file)            os.remove(final_audio)except:passreturn outclassMainWindow(QMainWindow):def__init__(self):        super().__init__()        self.setWindowTitle("PPT智能转数字人视频工具 v4.0 (修复版)")        self.setGeometry(100100950800)        self.setMinimumSize(900750)        self.ffmpeg_path = get_ffmpeg_path()        self.worker = None        self.init_ui()        self.load_voices()        self.apply_styles()definit_ui(self):        central_widget = QWidget()        self.setCentralWidget(central_widget)        main_layout = QVBoxLayout(central_widget)        main_layout.setContentsMargins(20202020)        main_layout.setSpacing(15)        title_layout = QHBoxLayout()        title_label = QLabel("PPT转数字人视频工具 (极速渲染)")        title_label.setFont(QFont("Microsoft YaHei"18, QFont.Bold))        title_layout.addWidget(title_label)if self.ffmpeg_path:            self.ffmpeg_tip = QLabel("✅ FFmpeg 已就绪")            self.ffmpeg_tip.setStyleSheet("color: #67C23A; font-weight: bold;")else:            self.ffmpeg_tip = QLabel("❌ 未找到FFmpeg")            self.ffmpeg_tip.setStyleSheet("color: #F56C6C; font-weight: bold;")        title_layout.addStretch()        title_layout.addWidget(self.ffmpeg_tip)        main_layout.addLayout(title_layout)        file_group = QGroupBox("文件选择")        file_layout = QVBoxLayout(file_group)        ppt_layout = QHBoxLayout()        self.edit_ppt = QLineEdit()        self.edit_ppt.setPlaceholderText("请选择PPT文件 (.pptx)")        btn_ppt = QPushButton("选择PPT")        btn_ppt.clicked.connect(self.choose_ppt)        ppt_layout.addWidget(QLabel("PPT文件:"), 0)        ppt_layout.addWidget(self.edit_ppt, 1)        ppt_layout.addWidget(btn_ppt, 0)        file_layout.addLayout(ppt_layout)        avatar_layout = QHBoxLayout()        avatar_left = QVBoxLayout()        ava_input = QHBoxLayout()        self.edit_avatar = QLineEdit()        self.edit_avatar.setPlaceholderText("可选:透明底PNG图片")        btn_avatar = QPushButton("选择数字人")        btn_avatar.clicked.connect(self.choose_avatar)        ava_input.addWidget(QLabel("数字人:"), 0)        ava_input.addWidget(self.edit_avatar, 1)        ava_input.addWidget(btn_avatar, 0)        avatar_left.addLayout(ava_input)        self.avatar_preview = QLabel("暂无图片")        self.avatar_preview.setAlignment(Qt.AlignCenter)        self.avatar_preview.setFixedHeight(100)        self.avatar_preview.setStyleSheet("border: 1px dashed #ccc; background-color: #fafafa;")        avatar_layout.addLayout(avatar_left, 1)        avatar_layout.addWidget(self.avatar_preview, 0)        file_layout.addLayout(avatar_layout)        main_layout.addWidget(file_group)        setting_group = QGroupBox("参数设置")        setting_layout = QVBoxLayout(setting_group)        voice_layout = QHBoxLayout()        self.combo_voice = QComboBox()        self.combo_rate = QComboBox()        self.combo_rate.addItems(["-50%""-20%""+0%""+20%""+50%"])        self.combo_rate.setCurrentIndex(2)        voice_layout.addWidget(QLabel("发音人:"), 0)        voice_layout.addWidget(self.combo_voice, 2)        voice_layout.addSpacing(20)        voice_layout.addWidget(QLabel("语速:"), 0)        voice_layout.addWidget(self.combo_rate, 1)        voice_layout.addStretch()        setting_layout.addLayout(voice_layout)        preset_layout = QHBoxLayout()        self.combo_preset = QComboBox()        self.combo_preset.addItems(["ultrafast       ✅ 最快","superfast       第二快","veryfast        第三快","faster          第四快","fast            第五快","medium          平衡","slow            慢","slower          很慢","veryslow        极慢"        ])        self.combo_preset.setCurrentIndex(0)        preset_layout.addWidget(QLabel("编码速度:"), 0)        preset_layout.addWidget(self.combo_preset, 1)        preset_layout.addStretch()        setting_layout.addLayout(preset_layout)        main_layout.addWidget(setting_group)        self.progress_bar = QProgressBar()        main_layout.addWidget(self.progress_bar)        btn_layout = QVBoxLayout()        gen_btn_layout = QHBoxLayout()        self.btn_preview_3 = QPushButton("📄 3页快速预览")        self.btn_preview_3.setMinimumHeight(40)        self.btn_preview_3.setStyleSheet("background-color: #e6a23c; color: white; font-weight:bold;")        self.btn_preview_3.clicked.connect(lambda: self.start_task(mode='preview_3'))        self.btn_preview_20s = QPushButton("⏱️ 20秒片段预览")        self.btn_preview_20s.setMinimumHeight(40)        self.btn_preview_20s.setStyleSheet("background-color: #409eff; color: white; font-weight:bold;")        self.btn_preview_20s.clicked.connect(lambda: self.start_task(mode='preview_20s'))        self.btn_start = QPushButton("🚀 生成完整视频")        self.btn_start.setMinimumHeight(40)        self.btn_start.setStyleSheet("background-color: #67C23A; color: white; font-weight:bold;")        self.btn_start.clicked.connect(lambda: self.start_task(mode='full'))        gen_btn_layout.addWidget(self.btn_preview_3, 1)        gen_btn_layout.addSpacing(10)        gen_btn_layout.addWidget(self.btn_preview_20s, 1)        gen_btn_layout.addSpacing(10)        gen_btn_layout.addWidget(self.btn_start, 1)        btn_layout.addLayout(gen_btn_layout)        ctrl_btn_layout = QHBoxLayout()        self.btn_pause = QPushButton("⏸️ 暂停")        self.btn_pause.setEnabled(False)        self.btn_stop = QPushButton("⏹️ 停止")        self.btn_stop.setEnabled(False)        self.btn_pause.clicked.connect(self.toggle_pause)        self.btn_stop.clicked.connect(self.stop_task)        ctrl_btn_layout.addStretch()        ctrl_btn_layout.addWidget(self.btn_pause, 1)        ctrl_btn_layout.addSpacing(10)        ctrl_btn_layout.addWidget(self.btn_stop, 1)        ctrl_btn_layout.addStretch()        btn_layout.addLayout(ctrl_btn_layout)        main_layout.addLayout(btn_layout)        self.log_text = QTextEdit()        self.log_text.setReadOnly(True)        main_layout.addWidget(QLabel("处理日志:"))        main_layout.addWidget(self.log_text)defapply_styles(self):        self.setStyleSheet("""            QMainWindow { background-color: #f5f7fa; }            QGroupBox { font-weight: bold; border: 1px solid #dcdfe6; border-radius: 8px; margin-top: 10px; padding-top: 15px; background-color: white; }            QLineEdit, QComboBox { border: 1px solid #dcdfe6; border-radius: 6px; padding: 8px; }            QPushButton { border-radius: 6px; }            QPushButton:hover { opacity: 0.9; }            QProgressBar { border: none; border-radius: 6px; height: 12px; background-color: #ecf5ff; }            QProgressBar::chunk { border-radius: 6px; background-color: #67C23A; }        """)defload_voices(self):try:            voices = asyncio.run(edge_tts.list_voices())for v in voices:if v["Locale"].startswith("zh"):                    self.combo_voice.addItem(v["FriendlyName"], v["ShortName"])except:passdefchoose_ppt(self):        f, _ = QFileDialog.getOpenFileName(self, "选择PPT""""PPT文件 (*.pptx)")if f: self.edit_ppt.setText(f)defchoose_avatar(self):        f, _ = QFileDialog.getOpenFileName(self, "选择数字人""""图片文件 (*.png *.jpg)")if f:            self.edit_avatar.setText(f)            pixmap = QPixmap(f).scaled(160100, Qt.KeepAspectRatio, Qt.SmoothTransformation)            self.avatar_preview.setPixmap(pixmap)deflog(self, msg):        self.log_text.append(msg)defget_preset(self):return self.combo_preset.currentText().strip().split()[0]defstart_task(self, mode='full'):ifnot self.ffmpeg_path:            QMessageBox.critical(self, "错误""请先安装FFmpeg")return        ppt_path = self.edit_ppt.text().strip()ifnot ppt_path ornot os.path.exists(ppt_path):            QMessageBox.warning(self, "提示""请选择PPT文件!")return        self.set_btn_enabled(False)        self.log_text.clear()        desktop = os.path.join(os.path.expanduser("~"), "Desktop")        out_dir = os.path.join(desktop, "PPT_视频输出")        self.worker = WorkerThread(            ppt_path,             self.edit_avatar.text().strip(),             self.combo_voice.currentData(),             self.combo_rate.currentText(),             self.get_preset(),             out_dir,             self.ffmpeg_path,            mode        )        self.worker.log_signal.connect(self.log)        self.worker.progress_signal.connect(self.progress_bar.setValue)        self.worker.finished_signal.connect(self.on_task_finished)        self.worker.start()deftoggle_pause(self):if self.worker: self.worker.toggle_pause()defstop_task(self):if self.worker: self.worker.stop()defon_task_finished(self, msg):        self.set_btn_enabled(True)        QMessageBox.information(self, "完成", msg)defset_btn_enabled(self, is_idle):        self.btn_preview_3.setEnabled(is_idle)        self.btn_preview_20s.setEnabled(is_idle)        self.btn_start.setEnabled(is_idle)        self.btn_pause.setEnabled(not is_idle)        self.btn_stop.setEnabled(not is_idle)if __name__ == "__main__":    app = QApplication(sys.argv)    window = MainWindow()    window.show()    sys.exit(app.exec_())

四、核心知识点总结(快速掌握关键技术)

这款工具融合了多个Python核心技术点,不仅能直接使用,还能帮助大家提升编程能力,以下是重点知识点总结,适合新手学习和进阶:

  1. PyQt5可视化开发:掌握QMainWindow、QWidget、布局管理器(QVBoxLayout、QHBoxLayout)、控件(按钮、输入框、进度条等)的使用,学会界面样式美化,实现用户友好的交互界面。

  2. 多线程编程(QThread):理解多线程的核心原理,学会使用QThread实现后台耗时操作,避免界面阻塞;掌握QMutex和QWaitCondition的使用,实现线程的暂停、唤醒和状态控制。

  3. PPT解析与处理:使用python-pptx库提取PPT文本和页面信息,使用win32com.client调用PowerPoint接口,将PPT页面导出为高清图片,实现PPT的自动化处理。

  4. 语音生成(edge-tts):掌握edge-tts库的使用,实现文本转语音,支持发音人、语速调节,处理无文本场景的静音生成,实现语音的自动化生成。

  5. 视频合成(FFmpeg):了解FFmpeg的核心功能,学会通过subprocess调用FFmpeg命令,实现图片、语音的合成,支持数字人叠加、编码速度调节,解决音画同步、重复帧等问题。

  6. 文件操作与异常处理:掌握os、shutil库的使用,实现文件夹创建、文件删除、路径处理;学会异常捕获和处理,确保工具运行稳定,避免因异常导致程序崩溃。

五、拓展场景与测试步骤(快速上手,灵活运用)

(一)拓展场景(不止于PPT转视频)

这款工具的核心逻辑可灵活拓展,适配多种实际场景,满足不同用户的需求:

  • 职场场景:企业汇报、产品宣讲、培训课件制作,将静态PPT转为带语音、数字人的动态视频,提升汇报和培训效果。

  • 自媒体场景:知识类短视频、PPT讲解视频制作,无需手动剪辑,一键生成,节省创作时间,提升内容产出效率。

  • 教育场景:老师制作线上课程、知识点讲解视频,将课件PPT转为视频,搭配语音讲解,方便学生观看和复习。

  • 拓展改造:可新增文字字幕生成功能、视频水印功能、背景音乐添加功能,还可适配更多图片格式、视频输出格式,满足个性化需求。

(二)测试步骤(零门槛上手,快速验证功能)

按照以下步骤操作,即可快速测试工具功能,顺利生成视频:

  1. 安装依赖:打开命令行,输入以下命令,安装工具所需的所有依赖包:

pip install pyqt5 python-pptx edge-tts moviepy imageio-ffmpeg pywin32

  1. 安装FFmpeg:确保电脑已安装FFmpeg(工具会自动检测,若未安装,需手动安装并配置环境变量,具体安装教程可自行搜索)。

  2. 运行代码:将上述完整代码复制到Python编辑器(如PyCharm、VS Code),运行代码,启动工具界面。

  3. 参数设置

  • 点击“选择PPT”,选择需要转换的PPT文件(仅支持.pptx格式);

  • 可选:点击“选择数字人”,选择透明底PNG图片(数字人会叠加在视频右下角);

  • 选择发音人和语速(默认语速为+0%,可根据需求调节);

  • 选择编码速度(默认“ultrafast”最快模式,追求画质可选择“medium”平衡模式)。

  1. 生成视频
  • 快速预览:点击“3页快速预览”,工具会处理前3页PPT,生成预览视频;

  • 片段预览:点击“20秒片段预览”,工具会生成前20秒的视频片段;

  • 完整生成:点击“生成完整视频”,工具会处理所有PPT页面,生成完整视频。

  1. 查看结果:视频生成完成后,会弹出提示框,告知视频保存路径(默认保存在桌面“PPT_视频输出”文件夹中),打开文件夹即可查看生成的视频。

  2. 异常处理:若生成失败,可查看“处理日志”,根据日志提示排查问题(常见问题:FFmpeg未安装、PPT文件损坏、数字人图片路径错误)。

结尾总结

这款PPT智能转数字人视频工具v4.0(修复版),完美解决了市面上同类工具的痛点,兼顾美观、功能与实用性,零门槛上手,无论是小白还是专业人士,都能轻松使用。不仅能帮你节省大量的时间和精力,还能让你的PPT内容更具传播力和吸引力。

同时,通过学习这款工具的代码,还能掌握PyQt5、多线程、PPT解析、视频合成等核心Python技术,提升自身编程能力。大家可以根据自己的需求,对工具进行拓展改造,实现更多个性化功能。

赶紧复制代码,测试起来吧!如果在使用过程中遇到问题,可查看日志提示,或留言交流,一起完善这款实用工具~

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-05-07 23:07:31 HTTP/2.0 GET : https://h.sjds.net/a/497710.html
  2. 运行时间 : 0.088585s [ 吞吐率:11.29req/s ] 内存消耗:4,410.81kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=97395d8cec365de6333370b353247626
  1. /yingpanguazai/ssd/ssd1/www/h.sjds.net/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/h.sjds.net/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/h.sjds.net/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/h.sjds.net/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/h.sjds.net/runtime/temp/ad153693ed39fba6d1bda2fe72512cde.php ( 12.06 KB )
  140. /yingpanguazai/ssd/ssd1/www/h.sjds.net/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000433s ] mysql:host=127.0.0.1;port=3306;dbname=h_sjds;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000530s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000288s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.001768s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000490s ]
  6. SELECT * FROM `set` [ RunTime:0.000202s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000541s ]
  8. SELECT * FROM `article` WHERE `id` = 497710 LIMIT 1 [ RunTime:0.002769s ]
  9. UPDATE `article` SET `lasttime` = 1778166451 WHERE `id` = 497710 [ RunTime:0.008681s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000247s ]
  11. SELECT * FROM `article` WHERE `id` < 497710 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001859s ]
  12. SELECT * FROM `article` WHERE `id` > 497710 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000471s ]
  13. SELECT * FROM `article` WHERE `id` < 497710 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000671s ]
  14. SELECT * FROM `article` WHERE `id` < 497710 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.001974s ]
  15. SELECT * FROM `article` WHERE `id` < 497710 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.000612s ]
0.090121s