欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Python創(chuàng)建一個視頻管理器并實現(xiàn)視頻截圖功能

 更新時間:2024年08月20日 10:05:21   作者:winfredzhang  
在這篇博客中,我將向大家展示如何使用 wxPython 創(chuàng)建一個簡單的圖形用戶界面 (GUI) 應(yīng)用程序,該應(yīng)用程序可以管理視頻文件列表、播放視頻,并生成視頻截圖,我們將逐步實現(xiàn)這些功能,并確保代碼易于理解和擴(kuò)展,感興趣的小伙伴跟著小編一起來看看吧

項目概述

本項目的目標(biāo)是創(chuàng)建一個視頻文件管理器應(yīng)用,它能夠:

  • 列出視頻文件:用戶可以選擇一個文件夾,應(yīng)用會顯示該文件夾中的所有視頻文件。
  • 顯示視頻時長:用戶點擊視頻文件后,可以查看視頻的時長信息。
  • 播放視頻:用戶雙擊視頻文件,應(yīng)用將調(diào)用默認(rèn)的媒體播放器播放視頻。
  • 生成視頻截圖:用戶可以選擇視頻并設(shè)定截圖時間間隔,應(yīng)用將生成視頻截圖,并將截圖存放在以視頻文件命名的文件夾中。
  • 自動打開截圖文件夾:截圖生成后,應(yīng)用會自動打開截圖文件夾以方便用戶查看。

所有代碼

import wx
import os
import datetime
import subprocess
import sys
import cv2  # Ensure OpenCV is installed
import threading

class FileListFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="視頻文件列表", size=(600, 400))

        self.panel = wx.Panel(self)
        self.current_path = ""

        self.file_list_ctrl = wx.ListCtrl(self.panel, style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
        self.file_list_ctrl.InsertColumn(0, "文件名")
        self.file_list_ctrl.InsertColumn(1, "大小")
        self.file_list_ctrl.InsertColumn(2, "修改時間")
        self.file_list_ctrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.on_file_selected)
        self.file_list_ctrl.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_file_double_clicked)

        self.path_label = wx.StaticText(self.panel, label="路徑:")
        self.path_textctrl = wx.TextCtrl(self.panel, style=wx.TE_READONLY)
        self.path_button = wx.Button(self.panel, label="選擇路徑")
        self.path_button.Bind(wx.EVT_BUTTON, self.on_select_path)

        self.interval_label = wx.StaticText(self.panel, label="截圖間隔(秒):")
        self.interval_textctrl = wx.TextCtrl(self.panel, value="1")
        self.capture_button = wx.Button(self.panel, label="生成截圖")
        self.capture_button.Bind(wx.EVT_BUTTON, self.on_capture)

        self.export_button = wx.Button(self.panel, label="導(dǎo)出為文本")
        self.export_button.Bind(wx.EVT_BUTTON, self.on_export)

        self.play_button = wx.Button(self.panel, label="播放")
        self.play_button.Bind(wx.EVT_BUTTON, self.on_play)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.path_label, 0, wx.ALL, 5)
        sizer.Add(self.path_textctrl, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 5)
        sizer.Add(self.path_button, 0, wx.ALL, 5)
        sizer.Add(self.interval_label, 0, wx.ALL, 5)
        sizer.Add(self.interval_textctrl, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 5)
        sizer.Add(self.capture_button, 0, wx.ALL, 5)
        sizer.Add(self.file_list_ctrl, 1, wx.EXPAND | wx.ALL, 5)
        sizer.Add(self.export_button, 0, wx.ALL, 5)
        sizer.Add(self.play_button, 0, wx.ALL, 5)
        self.panel.SetSizer(sizer)

    def on_select_path(self, event):
        dlg = wx.DirDialog(self, "選擇路徑", style=wx.DD_DEFAULT_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            self.current_path = dlg.GetPath()
            self.path_textctrl.SetValue(self.current_path)
            self.update_file_list()
        dlg.Destroy()

    def update_file_list(self):
        self.file_list_ctrl.DeleteAllItems()

        if not self.current_path:
            return

        file_list = self.search_video_files(self.current_path)
        for filename, file_path, file_size, modified_time in file_list:
            modified_time_str = datetime.datetime.fromtimestamp(modified_time).strftime("%Y-%m-%d %H:%M:%S")

            index = self.file_list_ctrl.InsertItem(self.file_list_ctrl.GetItemCount(), filename)
            self.file_list_ctrl.SetItem(index, 1, str(file_size))
            self.file_list_ctrl.SetItem(index, 2, modified_time_str)

    def search_video_files(self, directory):
        video_extensions = ['.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv', '.webm']
        file_list = []

        for root, dirs, files in os.walk(directory):
            for file in files:
                if os.path.splitext(file)[1].lower() in video_extensions:
                    file_path = os.path.join(root, file)
                    file_size = os.path.getsize(file_path)
                    modified_time = os.path.getmtime(file_path)
                    file_list.append((file, file_path, file_size, modified_time))

        return file_list

    def on_file_selected(self, event):
        selected_item = event.GetItem()
        file_name = selected_item.GetText()
        file_path = os.path.join(self.current_path, file_name)

        video = cv2.VideoCapture(file_path)
        fps = video.get(cv2.CAP_PROP_FPS)
        frame_count = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
        duration = frame_count / fps
        video.release()

        duration_str = str(datetime.timedelta(seconds=int(duration)))

        wx.MessageBox(
            f"文件名: {file_name}\n時長: {duration_str}",
            "視頻信息", wx.OK | wx.ICON_INFORMATION)

    def on_file_double_clicked(self, event):
        self.on_play(event)

    def on_play(self, event):
        selected_item = self.file_list_ctrl.GetFirstSelected()
        if selected_item != -1:
            file_name = self.file_list_ctrl.GetItemText(selected_item)
            file_path = os.path.join(self.current_path, file_name)
            if sys.platform.startswith('win'):
                subprocess.Popen(['start', '', file_path], shell=True)
            elif sys.platform.startswith('darwin'):
                subprocess.Popen(['open', file_path])
            elif sys.platform.startswith('linux'):
                subprocess.Popen(['xdg-open', file_path])
        else:
            wx.MessageBox("請先選擇要播放的文件", "提示", wx.OK | wx.ICON_INFORMATION)


    def on_export(self, event):
        dlg = wx.FileDialog(self, "保存為文本文件", wildcard="Text files (*.txt)|*.txt",
                            style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)

        if dlg.ShowModal() == wx.ID_OK:
            file_path = dlg.GetPath()
            with open(file_path, 'w') as file:
                for index in range(self.file_list_ctrl.GetItemCount()):
                    file.write(self.file_list_ctrl.GetItemText(index) + '\n')

    def on_capture(self, event):
        selected_item = self.file_list_ctrl.GetFirstSelected()
        if selected_item != -1:
            file_name = self.file_list_ctrl.GetItemText(selected_item)
            file_path = os.path.join(self.current_path, file_name)
            try:
                interval = int(self.interval_textctrl.GetValue())
            except ValueError:
                wx.MessageBox("請輸入有效的時間間隔(秒)", "錯誤", wx.OK | wx.ICON_ERROR)
                return

            thread = threading.Thread(target=self.capture_screenshots, args=(file_path, interval))
            thread.start()
        else:
            wx.MessageBox("請先選擇要生成截圖的文件", "提示", wx.OK | wx.ICON_INFORMATION)

    def capture_screenshots(self, file_path, interval):
        # 生成以視頻名稱命名的文件夾
        output_dir = os.path.join(self.current_path, os.path.splitext(os.path.basename(file_path))[0])
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        # 構(gòu)造 ffmpeg 命令
        cmd = [
            'ffmpeg',
            '-i', file_path,                 # 輸入視頻文件
            '-vf', f'fps=1/{interval}',      # 每隔 {interval} 秒截取一幀
            os.path.join(output_dir, 'screenshot_%03d.jpg')  # 輸出截圖路徑及文件名格式
        ]

        # 執(zhí)行命令
        subprocess.run(cmd, check=True)

        # 截圖完成后,自動打開文件夾
        if sys.platform.startswith('win'):
            subprocess.Popen(['explorer', output_dir])
        elif sys.platform.startswith('darwin'):
            subprocess.Popen(['open', output_dir])
        elif sys.platform.startswith('linux'):
            subprocess.Popen(['xdg-open', output_dir])

    # def capture_screenshots(self, file_path, interval):
    #     video = cv2.VideoCapture(file_path)
    #     fps = video.get(cv2.CAP_PROP_FPS)
    #     frame_count = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
    #     duration = frame_count / fps

    #     output_dir = os.path.join(self.current_path, os.path.splitext(os.path.basename(file_path))[0])  
    #     if not os.path.exists(output_dir):
    #         os.makedirs(output_dir)

    #     for sec in range(0, int(duration), interval):
            video.set(cv2.CAP_PROP_POS_MSEC, sec * 1000)
            success, image = video.read()
            if success:
                cv2.imwrite(os.path.join(output_dir, f"{sec}.png"), image)

        video.release()
        wx.CallAfter(wx.MessageBox, "截圖已生成", "完成", wx.OK | wx.ICON_INFORMATION)
        
        # Automatically open the folder containing screenshots
        if sys.platform.startswith('win'):
            subprocess.Popen(['explorer', output_dir], shell=True)
        elif sys.platform.startswith('darwin'):
            subprocess.Popen(['open', output_dir])
        elif sys.platform.startswith('linux'):
            subprocess.Popen(['xdg-open', output_dir])

if __name__ == "__main__":
    app = wx.App()
    frame = FileListFrame()
    frame.Show()
    app.MainLoop()

項目實現(xiàn)

讓我們一步一步實現(xiàn)這個項目。

1. 環(huán)境準(zhǔn)備

首先,你需要確保系統(tǒng)中安裝了以下工具:

  • Python 3.x:Python 是本項目的編程語言。
  • wxPython:用于創(chuàng)建圖形用戶界面。你可以使用以下命令安裝它:
pip install wxPython
  • ffmpeg:用于處理視頻文件和生成截圖。你可以從 ffmpeg 官網(wǎng) 下載并安裝。

2. 創(chuàng)建主窗口類

首先,我們創(chuàng)建一個主窗口類 FileListFrame,用于展示視頻文件列表并處理用戶交互。

import wx
import os
import datetime
import subprocess
import sys
import threading

class FileListFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="視頻文件管理器", size=(600, 400))

        self.panel = wx.Panel(self)
        self.current_path = ""

        # 創(chuàng)建文件列表控件
        self.file_list_ctrl = wx.ListCtrl(self.panel, style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
        self.file_list_ctrl.InsertColumn(0, "文件名")
        self.file_list_ctrl.InsertColumn(1, "時長")
        self.file_list_ctrl.InsertColumn(2, "大小")
        self.file_list_ctrl.InsertColumn(3, "修改時間")
        self.file_list_ctrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.on_file_selected)
        self.file_list_ctrl.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.on_play)

        # 創(chuàng)建路徑選擇控件
        self.path_label = wx.StaticText(self.panel, label="路徑:")
        self.path_textctrl = wx.TextCtrl(self.panel, style=wx.TE_READONLY)
        self.path_button = wx.Button(self.panel, label="選擇路徑")
        self.path_button.Bind(wx.EVT_BUTTON, self.on_select_path)

        # 創(chuàng)建導(dǎo)出和播放按鈕
        self.capture_button = wx.Button(self.panel, label="截圖")
        self.capture_button.Bind(wx.EVT_BUTTON, self.on_capture)

        # 創(chuàng)建截圖時間間隔輸入框
        self.interval_label = wx.StaticText(self.panel, label="截圖時間間隔(秒):")
        self.interval_textctrl = wx.TextCtrl(self.panel)

        # 創(chuàng)建布局
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.path_label, 0, wx.ALL, 5)
        sizer.Add(self.path_textctrl, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, 5)
        sizer.Add(self.path_button, 0, wx.ALL, 5)
        sizer.Add(self.file_list_ctrl, 1, wx.EXPAND | wx.ALL, 5)
        sizer.Add(self.interval_label, 0, wx.ALL, 5)
        sizer.Add(self.interval_textctrl, 0, wx.EXPAND | wx.ALL, 5)
        sizer.Add(self.capture_button, 0, wx.ALL, 5)
        self.panel.SetSizer(sizer)

在 __init__ 方法中,我們初始化了主窗口,并創(chuàng)建了一個 ListCtrl 控件用于顯示視頻文件列表。還添加了用于選擇路徑的按鈕和輸入截圖時間間隔的文本框。

3. 列出視頻文件

接下來,我們實現(xiàn)選擇路徑和列出視頻文件的功能:

    # 處理選擇路徑事件
    def on_select_path(self, event):
        dlg = wx.DirDialog(self, "選擇路徑", style=wx.DD_DEFAULT_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            self.current_path = dlg.GetPath()
            self.path_textctrl.SetValue(self.current_path)
            self.update_file_list()
        dlg.Destroy()

    # 更新文件列表
    def update_file_list(self):
        self.file_list_ctrl.DeleteAllItems()

        if not self.current_path:
            return

        file_list = self.search_video_files(self.current_path)
        for filename, file_path, file_size, modified_time in file_list:
            modified_time_str = datetime.datetime.fromtimestamp(modified_time).strftime("%Y-%m-%d %H:%M:%S")

            index = self.file_list_ctrl.InsertItem(self.file_list_ctrl.GetItemCount(), filename)
            self.file_list_ctrl.SetItem(index, 1, "待獲取")
            self.file_list_ctrl.SetItem(index, 2, str(file_size))
            self.file_list_ctrl.SetItem(index, 3, modified_time_str)

    # 搜索視頻文件
    def search_video_files(self, directory):
        video_extensions = ['.mp4', '.avi', '.mkv', '.mov', '.wmv', '.flv', '.webm']
        file_list = []

        for root, dirs, files in os.walk(directory):
            for file in files:
                if os.path.splitext(file)[1].lower() in video_extensions:
                    file_path = os.path.join(root, file)
                    file_size = os.path.getsize(file_path)
                    modified_time = os.path.getmtime(file_path)
                    file_list.append((file, file_path, file_size, modified_time))

        return file_list

這里我們通過遍歷用戶選擇的路徑,查找所有視頻文件,并將其添加到列表控件中。視頻文件的時長將在用戶點擊時獲取。

4. 顯示視頻時長

我們使用 ffmpeg 提供的功能來獲取視頻文件的時長。

    # 處理文件選擇事件
    def on_file_selected(self, event):
        selected_item = event.GetItem()
        file_name = selected_item.GetText()
        file_path = os.path.join(self.current_path, file_name)
        duration = self.get_video_duration(file_path)
        self.file_list_ctrl.SetItem(selected_item.GetId(), 1, duration)

    # 獲取視頻時長
    def get_video_duration(self, file_path):
        cmd = [
            'ffmpeg',
            '-i', file_path,
            '-hide_banner',
            '-loglevel', 'error',
            '-show_entries', 'format=duration',
            '-of', 'default=noprint_wrappers=1:nokey=1'
        ]
        result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        duration = float(result.stdout.strip())
        return str(datetime.timedelta(seconds=int(duration)))

在用戶選擇視頻文件時,on_file_selected 事件被觸發(fā),應(yīng)用會調(diào)用 ffmpeg 命令獲取視頻時長并顯示在列表中。

5. 播放視頻

用戶可以通過雙擊視頻文件來播放視頻。我們使用默認(rèn)的媒體播放器來實現(xiàn)播放功能:

    # 處理播放事件
    def on_play(self, event):
        selected_item = self.file_list_ctrl.GetFirstSelected()
        if selected_item != -1:
            file_name = self.file_list_ctrl.GetItemText(selected_item)
            file_path = os.path.join(self.current_path, file_name)
            if sys.platform.startswith('win'):
                subprocess.Popen(['start', '', file_path], shell=True)
            elif sys.platform.startswith('darwin'):
                subprocess.Popen(['open', file_path])
            elif sys.platform.startswith('linux'):
                subprocess.Popen(['xdg-open', file_path])
        else:
            wx.MessageBox("請先選擇要播放的文件", "提示", wx.OK | wx.ICON_INFORMATION)

通過調(diào)用系統(tǒng)命令,我們讓視頻文件可以使用系統(tǒng)默認(rèn)的播放器進(jìn)行播放。

6. 截取視頻截圖

用戶可以設(shè)置時間間隔,并對視頻進(jìn)行截圖。截圖將保存到以視頻文件名命名的文件夾中:

    # 處理截圖事件
    def on_capture(self, event):
        selected_item = self.file_list_ctrl.GetFirstSelected()
        if selected_item != -1:
            file_name = self.file_list_ctrl.GetItemText(selected_item)
            file_path = os.path.join(self.current_path, file_name)
            interval = int(self.interval_textctrl.GetValue())
            thread = threading.Thread(target=self.capture_screenshots, args=(file_path, interval))
            thread.start()
        else:
            wx.MessageBox("請先選擇要截圖的視頻文件", "提示", wx.OK | wx.ICON_INFORMATION)

    # 截取視頻截圖
    def capture_screenshots(self, file_path, interval):
        # 生成以視頻名稱命名的文件夾
        output_dir

 = os.path.join(self.current_path, os.path.splitext(os.path.basename(file_path))[0])
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)

        # 構(gòu)造 ffmpeg 命令
        cmd = [
            'ffmpeg',
            '-i', file_path,
            '-vf', f'fps=1/{interval}',
            os.path.join(output_dir, 'screenshot_%03d.jpg')
        ]

        # 執(zhí)行命令
        subprocess.run(cmd, check=True)

        # 截圖完成后,自動打開文件夾
        if sys.platform.startswith('win'):
            subprocess.Popen(['explorer', output_dir])
        elif sys.platform.startswith('darwin'):
            subprocess.Popen(['open', output_dir])
        elif sys.platform.startswith('linux'):
            subprocess.Popen(['xdg-open', output_dir])

7. 運(yùn)行應(yīng)用

最后,添加主函數(shù)以啟動應(yīng)用:

if __name__ == "__main__":
    app = wx.App(False)
    frame = FileListFrame()
    frame.Show()
    app.MainLoop()

效果如下

總結(jié)

在這篇博客中,我們使用 wxPython 和 ffmpeg 創(chuàng)建了一個視頻文件管理器。它不僅能管理和播放視頻,還能生成視頻截圖,并將截圖存放到特定的文件夾中。你可以根據(jù)需要進(jìn)一步擴(kuò)展這個應(yīng)用程序,例如增加視頻剪輯、視頻合并等功能。希望這篇博客能幫助你更好地理解 wxPython 和 ffmpeg 的使用方法,并激發(fā)你在項目中應(yīng)用這些技術(shù)的興趣。

以上就是使用Python創(chuàng)建一個視頻管理器并實現(xiàn)視頻截圖功能的詳細(xì)內(nèi)容,更多關(guān)于Python視頻截圖的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • scrapy-redis源碼分析之發(fā)送POST請求詳解

    scrapy-redis源碼分析之發(fā)送POST請求詳解

    這篇文章主要給大家介紹了關(guān)于scrapy-redis源碼分析之發(fā)送POST請求的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用scrapy-redis具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • python 實現(xiàn)一次性在文件中寫入多行的方法

    python 實現(xiàn)一次性在文件中寫入多行的方法

    今天小編就為大家分享一篇python 實現(xiàn)一次性在文件中寫入多行的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Python單元測試框架unittest使用方法講解

    Python單元測試框架unittest使用方法講解

    這篇文章主要介紹了Python單元測試框架unittest使用方法講解,本文講解了unittest概述、命令行接口、測試案例自動搜索、創(chuàng)建測試代碼、構(gòu)建測試套件方法等內(nèi)容,需要的朋友可以參考下
    2015-04-04
  • Django的URLconf中使用缺省視圖參數(shù)的方法

    Django的URLconf中使用缺省視圖參數(shù)的方法

    這篇文章主要介紹了Django的URLconf中使用缺省視圖參數(shù)的方法,Django是最著名的Python的web開發(fā)框架,需要的朋友可以參考下
    2015-07-07
  • python遞歸函數(shù)使用詳解

    python遞歸函數(shù)使用詳解

    遞歸函數(shù)是一種在函數(shù)內(nèi)部調(diào)用自身的編程技巧。在Python中,我們可以使用遞歸函數(shù)來解決一些需要重復(fù)執(zhí)行相同操作的問題。遞歸函數(shù)通常包含兩個部分:基本情況和遞歸情況?;厩闆r是指函數(shù)停止調(diào)用自身的條件,而遞歸情況是指函數(shù)調(diào)用自身來解決更小規(guī)模的問題。
    2023-09-09
  • 使用python-pptx操作PPT的示例詳解

    使用python-pptx操作PPT的示例詳解

    python對PPT演示文檔讀寫,是通過第三方庫python-pptx實現(xiàn)的,python-pptx是用于創(chuàng)建和更新?PowerPoint文件的?Python?庫。本文主要介紹了python-pptx操作PPT的相關(guān)示例,希望對大家有所幫助
    2023-01-01
  • Python永久配置國內(nèi)鏡像源安裝再也不用擔(dān)心卡頓

    Python永久配置國內(nèi)鏡像源安裝再也不用擔(dān)心卡頓

    這篇文章主要為大家介紹了Python如何永久配置國內(nèi)鏡像源,從此安裝再也不用擔(dān)心卡頓,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-10-10
  • python讀取文件名及后綴詳解

    python讀取文件名及后綴詳解

    下面小編就為大家分享一篇關(guān)于python讀取文件名及后綴的文章,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-10-10
  • mac PyCharm添加Python解釋器及添加package路徑的方法

    mac PyCharm添加Python解釋器及添加package路徑的方法

    今天小編就為大家分享一篇mac PyCharm添加Python解釋器及添加package路徑的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • Python使用Matplotlib實現(xiàn)雨點圖動畫效果的方法

    Python使用Matplotlib實現(xiàn)雨點圖動畫效果的方法

    這篇文章主要介紹了Python使用Matplotlib實現(xiàn)雨點圖動畫效果的方法,結(jié)合實例形式分析了win10安裝ffmpeg及animation函數(shù)的使用相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12

最新評論