摘要:核心子進程運行控制。由應用來看,關鍵是錄制屏幕和錄制攝像頭,以及用快捷鍵控制在這兩者之間切換。限制條件是超過三個月快捷鍵失效。實現分兩步安裝時在注冊表特定位置,假如是,寫入目錄相關信息。在程序運行時,檢測當前目錄是否存在于注冊表下。
錄制項目終于做完,不用總是提醒自己抓緊時間這樣來想問題了。
在完成之后帶著一些滿足感,回頭看看哪些地方是需要改進的,哪些地方又是有更好的替代方案,自己又有哪些不足。
??客戶希望用視頻+音頻的方式錄制下會議的內容。除了錄制會議室情況之外,會議中還有可能需要錄制電腦屏幕內容,比如在做PPT講解等,所以需要一個在兩種錄制方式之間快捷切換的軟件。除此之外,需要一個防止復制運行的機制和完整的安裝包。
1. 核心:subprocess子進程運行控制。??由應用來看,關鍵是錄制屏幕和錄制攝像頭,以及用快捷鍵控制在這兩者之間切換。
??我的實現是通過python3調用ffmpeg,ffmpeg實現錄制,python來完成切換。
??從開發角度來說,并不算難,拋去錄制這個功能,這個軟件實際上應該這樣描述:python完全控制ffmpeg.exe進程的應用。
??進一步地說,ffmpeg能做到的,軟件大部分都可以做到,不同的是可以添加快捷鍵控制等,可以用python對除了ffmpeg功能之外做一些必要的補充。比如,客戶在需求實現之前測試發現win10系統下自買的攝像頭運行時間長了之后會隨機的中斷錄制,賣家也無辦法解決,因為是win10系統兼容性問題。所以客戶提出在錄制異常中斷的情況下,能夠自動重新開始錄制。這個需求的滿足就依賴python對ffmpeg的補充。
??另外,完全控制ffmpeg進程關鍵在于如何自然退出。ffmpeg在cmd運行按下q鍵是退出,利用這一點往子進程輸入流寫入"q"實現了自然退出,保證了數據的正常寫入和保存,并且不會引發異常情況。如果不得益于這一點,用os.kill(process_id)等方式都很難去控制進程的正常退出。
??下面是代碼結構簡化版思維導圖:
??界面相當的簡單,主界面是一個按鈕+錄制時間顯示。
??
??功能性的右鍵菜單:
??
??設置界面:
??軟件為了客戶方便定制化使用,提供了必要的參數設置。實現時用到了configparser。快捷鍵部分還有待完善。
??
??程序主要的錄制狀態變化通過托盤圖標的來展示。三種錄制狀態的托盤圖標如下:
??為了盡可能少的讓主界面出現在錄制內容中,當失去焦點時,窗口就會隱藏,這大概也就是客戶能夠容忍的原因:)。
??界面實現用的是pyqt5,因為以前自己做過c#的winform和java的swing開發,界面的處理邏輯又大同小異,所以參照著qt的文檔這塊能夠比較順手的處理。
??pyqt源自qt,而qt的文檔非常全面,參照著文檔在寫pyqt代碼時注意一點與c++語法的區別就好了。
??如果能夠更深入的用pyqt開發,有想過寫一篇《qt大局觀》的總結,就是整理一下圖形界面開發的模型以及與qt相比的相同點不同點,一來是自己覺得如果有這樣一篇大局觀的介紹文章能夠幫助自己節省大量的時間;二來能夠幫助從其他語言切換到qt或者新學習qt的開發人員在查詢qt文檔之前有更清晰的思路,那就更好了。
??如果要寫這篇文章大致從以下幾個方面入手:
共同性,比如都是基于事件驅動3. 簡易的防復制運行機制
通常有哪些常用或特別的控件?
每個或某類控件都有哪些通用的事件?
窗體加載機制有何不同?
在qt開發時又是怎么樣的?
具體一點,比如quitOnLastWindowClosed()的效果是怎樣的?會帶來什么問題?
qt的信號槽機制相比winform事件機制有何不同?等等。
??這個機制的目的是限制不是通過安裝包安裝的,運行都要受到限制。限制條件是超過三個月快捷鍵失效。實現分兩步:
1.安裝時在注冊表特定位置,假如是A,寫入目錄相關信息。
2.在程序運行時,檢測當前目錄是否存在于注冊表A下。
??具體實現時,A位置下保存兩類信息,一類是正常安裝的目錄,比如以"INSTALL+時間"為鍵名稱,值為安裝目錄,時間用以區分多次安裝;另一類是在非安裝目錄第一次運行的時間,實際就一個而且不可改變,這樣保證了所有非安裝目錄都有同一個時間限制基礎。
??更完善的實現應該對所有的鍵值加密處理。
??這是第一個有自己署名的軟件,也是第一次從無到有完整的做出一個有安裝包的軟件。
??軟件打包分成了兩步:
用cx_Freeze將python代碼編譯為exe文件。編譯python代碼為exe一般常見的工具有py2exe、pyinstaller、cx_Freeze等,因為這次開發用的python3.6,而只有cx_Freeze對3.6支持最好,所以自然也就用了cx_Freeze。原本網上的教程看到cx_Freeze也是可以定制打包復雜安裝文件的,但是在自己的實驗過程中始終在access數據庫相關的模塊報錯。使用bdist_msi生成的簡單安裝包不夠用,而且中文支持不好。然后仔細看過一篇文檔,發現cx_Freeze推薦的inno setup。
用inno setup定制軟件安裝包。按照inno setup默認的生成安裝包向導實驗一遍后,發現這東西太強了太好用了,前面花在cx_Freeze上折騰的時間簡直是浪費。
inno setup使用類似配置文件的結構來定制安裝包所需要的功能。
最常用的應該是[Tasks]即任務節點,在該節點下面定義安裝包需要執行的任務。任務屬性有名稱、描述、觸發條件、可選屬性等,其他節點可通過任務的名稱來關聯任務。
比如給用戶添加是否開機啟動的選擇項,首先定義任務:
[Tasks] Name: "startupicon"; Description: "開機啟動"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
然后,當這個任務startupicon被選中需要執行時,在用戶電腦的啟動目錄添加快捷方式:
[Icons] Name: "{userstartup}{#MyAppName}"; Filename: "{app}{#MyAppExeName}"; Tasks: startupicon
這里[Icons]節點和[Tasks]關聯起來的屬性就是[Icons]的Tasks: startupicon。其他的Files等節點也可以用同樣的方式關聯任務。
一個完整的inno配置文件在保證邏輯性的同時還非常簡潔,這一點非常強大。本項目的打包文件參見目錄中的setup.iss文件。
不過它的強大還不止于這一點,另一個原因是inno自帶一個叫Pascal的腳本語言,這可就讓可定制性直接上升一個臺階。Pascal不僅內置常用的函數,還可以自己寫Pascal代碼。看過示例腳本過后,也就不難想象現在的下載網站下載下來的安裝包有各種各樣的廣告是怎么實現的了。
??版本管理軟件對開發人員來說就像一個保險柜一樣,重要性不言而喻。以前自己總是零零碎碎的接觸到git,始終沒有用git真正的來管理一個項目,這次利用這個軟件正好好好的學習git,不能再忘了。
??以下自己按照使用邏輯再手敲一遍常用git(version:2.16.2.windows)管理命令及注釋:
git init 夢開始的地方 git status 查看項目狀態,使用率最高 git add/. 將文件修改讓git管理 git reset HEAD 撤銷git管理 git checkout -- 撤銷修改(未add之前) git rm [-r] 刪除git已管理的文件,文件被刪除 git rm [-r] --cached 撤銷git已管理的文件,文件仍存在 撤銷刪除跟撤銷修改一樣. git commit -m "注釋" 提交修改并備注修改緣由 git log 提交記錄 git reflog 命令歷史記錄 git reset --hard HEAD^^/HEAD~2/commit_id 回退到上上個版本或者回到指定commit_id版本 git pull origin master 與遠程倉庫origin下的master分支同步 git push origin master 將本地的修改推送到遠程倉庫origin下的master分支 git remote -v 查看遠程倉庫信息 git branch 查看全部分支 git branch 創建分支 git checkout 切換到分支 git checkout -b 創建分支并切換到該分支 git branch -d/-D 刪除分支 git merge [--no-ff保留分支信息] 合并分支 git stash [list] [apply恢復] [drop刪除] [pop恢復并刪除] 將修改臨時保存
暫時熟練的就這些,以后再更新。
軟件代碼發布在record-camera-and-screen。
創建了兩個分支gutin和dev。gutin是給客戶的版本,dev是自己想在這個軟件上進一步的完善。
??軟件運行效果:在分辨率為1024x768、幀率30/s、h264編碼、i5 cpu threads=4的情況下錄制,cpu占有率保持在30%~40%之間(這是ffmpeg的功勞)。
??開發分兩次提出,客戶第一次的需求主要是錄制,第二次是調整和增加附加功能。兩次合作及時完成了客戶的需求,都得到了用戶滿意的反饋。
加深了對python的了解,更熟練的編寫python代碼。
在開發過程中,練習使用git管理自己的代碼。并且利用版本回退幫助自己查找bug引發的原因,相信以后git會成為我開發工作中必不可少的幫手。這次不同的是,是在自己一手寫出來的代碼基礎上進行管理,所以得心應手很多。以往總是試著去github上clone別人的項目別人的代碼,作為一個新手,自己首先就面對的是不熟悉的項目和代碼,如果說在這個基礎上再學習git的操作和概念,其實是很難的。所以以前總是沒能好好的掌握git。
開發這個軟件第一目的是再學習如何解決在開發過程中遇到的問題。
這次開發遇到最大的難題是write(q),為什么這么說?確定是不是采用python+ffmpeg.exe的形式來實現的關鍵點在于對ffmpeg.exe進程的完全控制。首先,查看了subprocess的文檔,確定了完全控制一個子進程不成問題;然后在cmd下實驗了攝像頭錄制和屏幕錄制,就是ffmpeg在多帶帶運行的情況下,實現錄制功能。這兩點實驗過后都沒有問題,然后自以為兩者的結合會順其自然的順利。結果就卡在了停止錄制時,怎么處理ffmpeg進程的退出方式。
第一次實驗是Popen.terminate()和kill(),實際發現ffmpeg根本無動于衷。[原因待確認]
然后用Popen.send_signal(CTRL_C_EVENT)確實是可以控制ffmpeg進程退出了,結果看錄制的視頻,最后一部分錄制內容丟失了,很顯然是ffmpeg不正常退出導致的。由此也明白了,光退出還不行,還得自然的退出。雖然知道凡強制的方式必定不是自然的,期間抱著試試的態度也用到了os.kill(),結果果然不如人愿。
然后回頭復盤,想著CTRL_C_EVENT是模擬按鍵進行退出,那么模擬q鍵退出是不是可行呢?CTRL_C_EVENT是python提供的,那么怎么模擬自定義按鍵呢?接著就嘗試了stdin.write("q")方式,結果令人振奮,不僅錄制內容完整,而且沒有強制退出時偶爾引起的程序異常。事實證明這樣的處理方式是最自然的。還記得當時解決這個難題是多么的開心和滿足,這種滿足感也正是自己的開發樂趣所在。不過解決舊問題的同時,常常也許會引發新的問題。與輸入流交互的write("q")方式也就必須讓Popen(universal_newlines=True),而這后面也凸顯了ffmpeg對中文支持不太友好的問題,不過都得到了解決。
最后經過這個軟件的開發,讓自己從整體上對軟件有了一個新的認識。
任何一個軟件簡潔到可以用一句話說清楚。知道最終的目的是什么,從一個模型框架開始,我們所做的工作無非就是在這個模型之上添磚加瓦。軟件的不同之處在于,包含的磚瓦種類數目,每種磚每個瓦的開發難度,以及它們用什么樣的方式合在一起。最終構建成一座高樓大廈。收獲了完成一件作品時的喜悅,同時,也看到了自己能力的局限性。
想構建更強更大的軟件不光是要提升自己的能力,找到一個好的團隊,并一起合作創造才是最佳途徑。
完善快捷鍵9. 個人其他開發項目
錄制狀態切換音效和添加動畫【學習pyqt的繪制】
視頻輸出優化:添加水印和標簽等
界面美化:用圓形框取代方形按鈕
添加支付接口
添加實時錄制預覽窗口
改成個人的演講練習錄制工具
github: www.github.com/ilinxiao
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/41903.html
摘要:接著想使用播放視頻,按照官方教程只要將的變量修改為視頻文件名即可,程序如下在上查看代碼片派生到我的代碼片但是始終無法獲取視頻圖像,貌似這個問題很普遍,以至在官方教程的程序下面都提示說請確認或者已經正確安裝。 博主一開始使用python2.7和Opencv2.4.10來獲取攝像頭圖像,程序如下: [plain] view plain copy 在CODE上查看代碼片派生到我的代碼片 ...
閱讀 2692·2023-04-25 19:13
閱讀 4009·2021-09-22 15:34
閱讀 3052·2019-08-30 14:23
閱讀 1461·2019-08-29 17:17
閱讀 1603·2019-08-29 16:05
閱讀 1537·2019-08-29 13:26
閱讀 1217·2019-08-29 13:19
閱讀 553·2019-08-29 13:16