当前位置:首页>python>ffmpeg+python可视化分割视频

ffmpeg+python可视化分割视频

  • 2026-07-04 08:23:37
ffmpeg+python可视化分割视频

字数 3020,阅读大约需 16 分钟

ffmpeg+python可视化分割视频

日常处理视频时,你大概率遇到过这样的需求:

录了一堂长课、一场直播,想拆成几段分发;下载的影视素材,需要截取中间片段;甚至只是想把大文件切成两半方便传输。

用专业剪辑软件吧,不仅参数调节复杂,导出还非常耗时间;找在线工具吧,上传慢还有隐私风险;记FFmpeg命令吧,参数太多每次都要查。

有没有一种「无损、极速、可视化、完全本地」的切分工具?

为了这个目标,我前后迭代了三个版本,踩了一堆前端沙箱的坑,最终找到了最稳妥的实现方式。

最朴素的解法:一行命令搞定无损切分

熟悉FFmpeg的朋友都知道,视频切分分两种思路:重编码切分和流复制切分。

重编码可以精确到帧,但速度慢、吃CPU,还会损失画质;而流复制(-c copy 直接拆分视频封装数据流,不做任何重新编码,速度只取决于硬盘读写,画质零损失,文件体积和原片完全一致,是日常快速切分的首选。

命令非常简洁:

ffmpeg -ss 00:05:00 -t 00:10:00 -i 输入视频.mp4 -c copy 输出片段.mp4

优点很明显:极致速度、无损画质、零额外体积。

但缺点也同样突出:纯命令行不够直观,切分点要手动计算时间,调整位置全靠猜,新手基本望而却步。

于是很自然地想到:给它加个可视化界面,不就完美了?

优雅但踩坑的HTML路线

第一反应是做HTML单文件版——双击就能打开,不用装Python,不用装运行库,听起来就很优雅。

理想很丰满,现实却全是坑,前前后后踩了四五道坎:

1. Web Worker 跨域限制

直接双击HTML用file:// 协议打开时,浏览器的安全策略会禁止加载外部Web Worker脚本,而FFmpeg.wasm默认依赖Worker运行,直接罢工报错:

Script at 'xxx' cannot be accessed from origin 'null'.

一开始的解决方案是禁用Worker,强制单线程运行,虽然性能略降,但至少能跑。

2. CDN 网络依赖

默认的FFmpeg.wasm依赖境外CDN加载核心文件,国内访问经常超时失败,离线环境更是完全用不了。
为了做到真正的单文件,我尝试把20MB的WASM核心转成Base64,整体内嵌进HTML里,彻底摆脱网络依赖。

3. 打包后的路径检测报错

把库文件内嵌后,新的问题又来了:webpack打包的上层封装库会自动读取脚本的src属性推断资源路径,内嵌到HTML后没有了src属性,直接抛出:

Automatic publicPath is not supported in this browser

最后只能弃用上层封装,直接调用原生编译的FFmpeg核心,手动通过locateFile指定WASM路径,才绕过了这个问题。

4. 国内镜像不稳定

好不容易解决了技术问题,又发现国内常用的jsDelivr镜像经常抽风,下载20MB的核心文件断断续续,自动生成脚本直接报IncompleteRead中断。

折腾到最后我发现:为了「不用装环境」这一个优点,付出了太多兼容性代价。20多MB的HTML文件打开慢、浏览器内存占用高,大视频处理还容易崩溃,实际体验远不如本地程序。

回归本质:Python+Tkinter打造本地GUI工具

绕了一圈回来发现,最稳妥的方案,反而是最朴素的本地GUI。

import tkinter as tk
from
 tkinter import ttk, filedialog, messagebox
import
 subprocess
import
 os
import
 tempfile
from
 PIL import Image, ImageTk


# -------------------------- 工具函数 --------------------------

def
 format_time(seconds):
    """秒数转 时:分:秒.毫秒 格式"""

    h = int(seconds // 3600)
    m = int((seconds % 3600) // 60)
    s = seconds % 60
    return
 f"{h:02d}:{m:02d}:{s:05.2f}"


def
 get_video_duration(ffprobe_path, video_path):
    """调用 ffprobe 获取视频总时长"""

    cmd = [
        ffprobe_path,
        "-v"
, "error",
        "-show_entries"
, "format=duration",
        "-of"
, "default=noprint_wrappers=1:nokey=1",
        video_path
    ]
    result = subprocess.run(cmd, capture_output=True, text=True, encoding="utf-8")
    return
 float(result.stdout.strip())


def
 extract_frame(ffmpeg_path, video_path, time_sec, output_path):
    """截取指定时间点的视频帧用于预览"""

    cmd = [
        ffmpeg_path,
        "-ss"
, str(time_sec),
        "-i"
, video_path,
        "-vframes"
, "1",
        "-q:v"
, "2",
        "-y"
,
        output_path
    ]
    subprocess.run(cmd, capture_output=True, check=True, creationflags=subprocess.CREATE_NO_WINDOW)


# -------------------------- 自定义时间轴控件 --------------------------

class
 TimeAxisCanvas(tk.Canvas):
    def
 __init__(self, parent, **kwargs):
        super
().__init__(parent, **kwargs)
        self
.total_duration = 0.0
        self
.cut_points = []
        self
.current_position = 0.0
        self
.dragging_index = -1
        self
.margin = 20

        # 事件绑定

        self
.bind("<Button-1>", self.on_mouse_down)
        self
.bind("<B1-Motion>", self.on_mouse_drag)
        self
.bind("<ButtonRelease-1>", self.on_mouse_up)
        self
.bind("<Double-Button-1>", self.on_double_click)
        self
.bind("<Configure>", lambda e: self.redraw())

        # 回调函数

        self
.position_callback = None  # 位置确认后触发(单击、拖动结束)
        self
.points_changed_callback = None  # 切分点列表变化触发

    def
 set_total_duration(self, duration):
        self
.total_duration = duration
        self
.current_position = 0.0
        self
.cut_points.clear()
        if
 self.points_changed_callback:
            self
.points_changed_callback()
        self
.redraw()

    def
 add_cut_point(self, time_sec):
        if
 self.total_duration <= 0:
            return

        time_sec = max(0.1, min(time_sec, self.total_duration - 0.1))
        # 0.5秒内去重

        for
 t in self.cut_points:
            if
 abs(t - time_sec) < 0.5:
                return

        self
.cut_points.append(time_sec)
        self
.cut_points.sort()
        if
 self.points_changed_callback:
            self
.points_changed_callback()
        self
.redraw()

    def
 remove_cut_point(self, index):
        if
 0 <= index < len(self.cut_points):
            del
 self.cut_points[index]
            if
 self.points_changed_callback:
                self
.points_changed_callback()
            self
.redraw()

    def
 time_to_x(self, time_sec):
        if
 self.total_duration <= 0:
            return
 self.margin
        width = self.winfo_width() - 2 * self.margin
        return
 self.margin + time_sec / self.total_duration * width

    def
 x_to_time(self, x):
        width = self.winfo_width() - 2 * self.margin
        if
 width <= 0:
            return
 0.0
        x = max(self.margin, min(x, self.margin + width))
        return
 (x - self.margin) / width * self.total_duration

    def
 redraw(self):
        self
.delete("all")
        w = self.winfo_width()
        h = self.winfo_height()
        y_center = h // 2

        # 背景

        self
.create_rectangle(0, 0, w, h, fill="#f8f8f8", outline="")

        if
 self.total_duration <= 0:
            self
.create_text(w // 2, h // 2, text="请先打开视频", fill="#999", font=("微软雅黑", 12))
            return


        # 时间轴主线

        self
.create_line(self.margin, y_center, w - self.margin, y_center, fill="#bbb", width=2)

        # 刻度与时间标签

        tick_count = 6
        for
 i in range(tick_count + 1):
            t = self.total_duration * i / tick_count
            x = self.time_to_x(t)
            self
.create_line(x, y_center - 6, x, y_center + 6, fill="#888", width=1)
            self
.create_text(x, y_center + 22, text=format_time(t), fill="#888", font=("微软雅黑", 9))

        # 切分点(红色三角)

        for
 t in self.cut_points:
            x = self.time_to_x(t)
            points = [x, y_center - 12, x - 7, y_center, x + 7, y_center]
            self
.create_polygon(points, fill="#d93025", outline="#d93025", width=2)

        # 当前预览位置(蓝色竖线)

        curr_x = self.time_to_x(self.current_position)
        self
.create_line(curr_x, y_center - 18, curr_x, y_center + 18, fill="#0078d4", width=2)

    def
 on_mouse_down(self, event):
        if
 self.total_duration <= 0:
            return

        x = event.x

        # 检测是否点中切分点(准备拖动)

        for
 i, t in enumerate(self.cut_points):
            px = self.time_to_x(t)
            if
 abs(x - px) < 10:
                self
.dragging_index = i
                return


        # 单击空白处:立即跳转并预览

        t = self.x_to_time(x)
        self
.current_position = t
        self
.redraw()
        if
 self.position_callback:
            self
.position_callback(t)

    def
 on_mouse_drag(self, event):
        """拖动过程仅更新界面,不抽帧,保证流畅"""

        if
 self.dragging_index < 0 or self.total_duration <= 0:
            return

        x = event.x
        t = self.x_to_time(x)
        t = max(0.1, min(t, self.total_duration - 0.1))

        self
.cut_points[self.dragging_index] = t
        self
.cut_points.sort()
        self
.dragging_index = self.cut_points.index(t)
        self
.current_position = t

        # 仅重绘时间轴,不触发抽帧

        self
.redraw()
        if
 self.points_changed_callback:
            self
.points_changed_callback()

    def
 on_mouse_up(self, event):
        """拖动结束后再更新预览"""

        if
 self.dragging_index >= 0 and self.position_callback:
            self
.position_callback(self.current_position)
        self
.dragging_index = -1

    def
 on_double_click(self, event):
        if
 self.total_duration <= 0:
            return

        t = self.x_to_time(event.x)
        self
.add_cut_point(t)


# -------------------------- 主窗口 --------------------------

class
 VideoCutterApp(tk.Tk):
    def
 __init__(self):
        super
().__init__()
        self
.title("视频快速切分工具(流复制模式)")
        self
.geometry("1100x680")
        self
.minsize(950, 600)

        self
.video_path = ""
        self
.ffmpeg_path = "ffmpeg.exe"
        self
.ffprobe_path = "ffprobe.exe"
        self
.temp_frame = os.path.join(tempfile.gettempdir(), "video_cut_preview.jpg")
        self
.preview_photo = None

        # 预览区固定尺寸(16:9)

        self
.PREVIEW_WIDTH = 720
        self
.PREVIEW_HEIGHT = 405

        self
._build_ui()

    def
 _build_ui(self):
        # 顶部工具栏

        top_frame = ttk.Frame(self, padding=10)
        top_frame.pack(fill=tk.X)

        ttk.Button(top_frame, text="打开视频", command=self.open_video).pack(side=tk.LEFT, padx=5)
        ttk.Button(top_frame, text="设置FFmpeg路径", command=self.set_ffmpeg_path).pack(side=tk.LEFT, padx=5)
        ttk.Button(top_frame, text="添加当前位置", command=self.add_current_point).pack(side=tk.LEFT, padx=5)

        self
.btn_export = ttk.Button(top_frame, text="导出所有片段", command=self.export_segments, state=tk.DISABLED)
        self
.btn_export.pack(side=tk.LEFT, padx=5)

        self
.lbl_duration = ttk.Label(top_frame, text="总时长:--:--:--")
        self
.lbl_duration.pack(side=tk.RIGHT, padx=5)

        # 主内容分栏

        main_frame = ttk.Frame(self, padding=(10, 0, 10, 10))
        main_frame.pack(fill=tk.BOTH, expand=True)

        paned = ttk.PanedWindow(main_frame, orient=tk.HORIZONTAL)
        paned.pack(fill=tk.BOTH, expand=True)

        # 左侧预览区(固定尺寸容器,修复窗口跳动)

        preview_frame = ttk.LabelFrame(paned, text="画面预览", padding=10)
        paned.add(preview_frame, weight=4)

        # 固定尺寸容器,禁止子控件撑大父容器

        preview_container = tk.Frame(
            preview_frame, 
            width=self.PREVIEW_WIDTH, 
            height=self.PREVIEW_HEIGHT,
            bg="#111"
        )
        preview_container.pack_propagate(False)  # 关键:锁定容器尺寸
        preview_container.pack(expand=True)

        self
.lbl_preview = tk.Label(
            preview_container, 
            text="请先打开视频文件",
            bg="#111"
            fg="#888"
            font=("微软雅黑", 14)
        )
        self
.lbl_preview.pack(expand=True, fill=tk.BOTH)

        # 右侧切分点管理

        points_frame = ttk.LabelFrame(paned, text="切分点列表", padding=10)
        paned.add(points_frame, weight=1)

        self
.list_points = tk.Listbox(points_frame, font=("微软雅黑", 10))
        self
.list_points.pack(fill=tk.BOTH, expand=True, pady=(0, 10))

        ttk.Button(points_frame, text="删除选中", command=self.remove_selected_point).pack(fill=tk.X)

        tip = ttk.Label(
            points_frame,
            text="提示:\n1. 单击时间轴:预览画面\n2. 双击时间轴:添加切分点\n3. 拖动红色三角:调整位置",
            foreground="#666", font=("微软雅黑", 9), justify=tk.LEFT
        )
        tip.pack(anchor=tk.W, pady=(10, 0))

        # 底部时间轴

        timeline_frame = ttk.LabelFrame(self, text="时间轴", padding=(10, 5, 10, 10))
        timeline_frame.pack(fill=tk.X, padx=10, pady=(0, 10))

        self
.time_axis = TimeAxisCanvas(timeline_frame, height=80, highlightthickness=0, bg="#f8f8f8")
        self
.time_axis.pack(fill=tk.X)
        self
.time_axis.position_callback = self.update_preview
        self
.time_axis.points_changed_callback = self.refresh_point_list

        # 状态栏

        self
.status_var = tk.StringVar(value="就绪")
        ttk.Label(self, textvariable=self.status_var, anchor=tk.W, padding=(10, 5)).pack(fill=tk.X, side=tk.BOTTOM)

    def
 set_ffmpeg_path(self):
        path = filedialog.askopenfilename(title="选择 ffmpeg.exe", filetypes=[("可执行文件", "*.exe")])
        if
 path:
            self
.ffmpeg_path = path
            self
.ffprobe_path = os.path.join(os.path.dirname(path), "ffprobe.exe")
            messagebox.showinfo("设置成功", f"FFmpeg 路径已设置:\n{path}")

    def
 open_video(self):
        path = filedialog.askopenfilename(
            title="选择视频文件",
            filetypes=[("视频文件", "*.mp4 *.mkv *.avi *.mov *.flv *.ts *.wmv *.m4v")]
        )
        if
 not path:
            return

        self
.video_path = path
        try
:
            duration = get_video_duration(self.ffprobe_path, path)
            self
.time_axis.set_total_duration(duration)
            self
.lbl_duration.config(text=f"总时长:{format_time(duration)}")
            self
.btn_export.config(state=tk.NORMAL)
            self
.update_preview(0)
            self
.status_var.set("视频加载完成,可在下方时间轴操作")
        except
 Exception as e:
            messagebox.showerror(
                "读取失败"
,
                f"无法读取视频信息,请检查 FFmpeg 路径是否正确。\n\n错误详情:{str(e)}"

            )

    def
 update_preview(self, time_sec):
        if
 not self.video_path:
            return

        try
:
            extract_frame(self.ffmpeg_path, self.video_path, time_sec, self.temp_frame)
            img = Image.open(self.temp_frame)
            # 按固定预览尺寸等比缩放,不改变容器大小

            img.thumbnail((self.PREVIEW_WIDTH, self.PREVIEW_HEIGHT), Image.Resampling.LANCZOS)
            self
.preview_photo = ImageTk.PhotoImage(img)
            self
.lbl_preview.config(image=self.preview_photo, text="")
        except
 Exception:
            self
.lbl_preview.config(text="预览加载失败", image="")

    def
 add_current_point(self):
        self
.time_axis.add_cut_point(self.time_axis.current_position)

    def
 remove_selected_point(self):
        sel = self.list_points.curselection()
        if
 sel:
            self
.time_axis.remove_cut_point(sel[0])

    def
 refresh_point_list(self):
        self
.list_points.delete(0, tk.END)
        for
 t in self.time_axis.cut_points:
            self
.list_points.insert(tk.END, format_time(t))
        self
.btn_export.config(state=tk.NORMAL if self.time_axis.cut_points else tk.DISABLED)

    def
 export_segments(self):
        if
 not self.video_path or not self.time_axis.cut_points:
            messagebox.showwarning("提示", "请先添加至少一个切分点")
            return


        # 生成所有分段区间

        points = [0.0] + self.time_axis.cut_points + [self.time_axis.total_duration]
        segments = [(points[i], points[i+1]) for i in range(len(points)-1)]

        out_dir = filedialog.askdirectory(title="选择输出文件夹")
        if
 not out_dir:
            return


        base_name = os.path.splitext(os.path.basename(self.video_path))[0]
        ext = os.path.splitext(self.video_path)[1]

        success = 0
        total = len(segments)
        self
.btn_export.config(state=tk.DISABLED)
        self
.status_var.set("开始导出...")
        self
.update()

        for
 idx, (start, end) in enumerate(segments):
            out_path = os.path.join(out_dir, f"{base_name}_片段{idx+1}{ext}")
            duration = end - start
            cmd = [
                self
.ffmpeg_path,
                "-ss"
, str(start),
                "-t"
, str(duration),
                "-i"
, self.video_path,
                "-c"
, "copy",
                "-y"
,
                out_path
            ]
            try
:
                subprocess.run(
                    cmd, check=True, capture_output=True,
                    text=True, encoding="utf-8",
                    creationflags=subprocess.CREATE_NO_WINDOW
                )
                success += 1
                self
.status_var.set(f"正在导出:{idx+1}/{total}")
                self
.update()
            except
 subprocess.CalledProcessError as e:
                messagebox.showwarning("导出出错", f"片段 {idx+1} 导出失败:\n{e.stderr}")

        self
.btn_export.config(state=tk.NORMAL)
        self
.status_var.set(f"导出完成,成功 {success}/{total} 个片段")
        messagebox.showinfo("导出完成", f"成功导出 {success}/{total} 个视频片段")


if
 __name__ == "__main__":
    app = VideoCutterApp()
    app.mainloop()

用Python自带的Tkinter做界面,直接调用本地已有的BtbN版FFmpeg,所有问题迎刃而解:

  • • ✅ 完全离线运行,没有任何网络依赖,不会出现加载失败
  • • ✅ 性能和原生命令行完全一致,流复制极速无损
  • • ✅ 界面交互更流畅,没有浏览器沙箱的各种限制
  • • ✅ 代码轻量,仅需一个额外图片处理库

最终工具的核心功能

1. 可视化时间轴,所见即所得

  • 单击跳转:时间轴上任意一点单击,立即预览对应画面
  • 双击加点:双击时间轴快速添加红色切分点
  • 拖动调整:按住红色三角拖动,自由调整切分位置

2. 细节打磨,体验拉满

  • 固定预览窗口:锁定16:9预览容器,彻底解决不同比例视频导致窗口忽大忽小的跳动问题
  • 流畅拖动优化:拖动过程中仅更新时间轴标线,松手后再刷新预览画面,避免频繁调用FFmpeg抽帧造成卡顿
  • 切分点列表管理:右侧列表清晰展示所有切分点,支持一键删除选中项

3. 一键批量导出,无损极速

设置好所有切分点后,只需选择输出文件夹,程序会自动一次性导出所有片段。全程采用流复制模式,画质零损失,十几GB的视频几十秒就能完成切分,速度只受硬盘读写限制。

极简使用步骤

  1. 1. 准备好BtbN版FFmpeg(本地已有可直接使用)
  2. 2. 安装唯一依赖:pip install pillow
  3. 3. 运行脚本,先设置FFmpeg路径,再打开视频即可操作

工具的取舍之道

这次折腾下来最大的感受是:很多时候「听起来更优雅」的方案,实际落地未必最好。

纯网页单文件、零安装的概念很酷,但浏览器安全沙箱、网络依赖、性能限制都是绕不开的坎;而看似传统的本地GUI,反而在稳定性、性能、易用性上全面占优。

工具永远是服务于人,而非用来炫技。对视频切分这种重本地文件、重性能的场景,本地程序永远是最踏实的选择。

如果你也经常需要拆分视频,不妨试试这个小工具——比剪辑软件省心,比命令行直观,用过就再也回不去了。

最新文章

随机文章

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