DS1819 对应版本的FFMPEG_Qt音视频开发33-ffmpeg安卓版
## 一、前言
一直都想搞個安卓版本的視頻監控程序,很早以前弄過一個,采用的是早期的ffmpeg2的lib文件,對于現在眾多的網絡流媒體格式,支持有限,而且新的Qt編寫安卓程序,結構上也變動了,新的安卓系統權限要求也和以前處理不一樣了,現在需要動態授權,以前是直接配置文件寫好需要哪些權限就行,所以近期特意全部重寫了一遍安卓版本的視頻監控程序,內核還是采用的ffmpeg,換成了最新的ffmpeg4版本,在ubuntu系統上用安卓編譯器編譯了對應的lib文件,然后放到win上編寫Qt+安卓程序。
為了統一管理一個版本的ffmpeg視頻監控內核程序,直接在現有的程序上修改,增加了動態申請權限的代碼,同時對應的進度條和復選框等指示器放大,方便選中,通道畫面限定默認4個,可以自行增加畫面數量,一開始測試保存截圖和視頻文件的時候,發現死活不成功,后面動態權限申請成功以后,把把成功,這里搞了很久,原來對不一樣的安卓系統處理要求不一樣。新時代新技術層出不窮,迭代真是非常的快,想要保持活力看來還得不斷的學習及了解新技術新知識。一個有前途的程序員每天60%的時間要拿出來學習研究,40%用來應付工作,這樣每兩年工資可翻一倍,而且最要命的是程序員也是要有一些天賦的,并非所有人都適合,大部分程序員把時間都扔在了業務邏輯之中,最后被淘汰!這也是35歲中年危機的主要原因。事實上有實力的程序員越老越值錢,扯遠了!
## 二、功能特點
1. 多線程實時播放視頻流+本地視頻+USB攝像頭等。
2. 支持windows+linux+mac,支持ffmpeg3和ffmpeg4,支持32位和64位。
3. 多線程顯示圖像,不卡主界面。
4. 自動重連網絡攝像頭。
5. 可設置邊框大小即偏移量和邊框顏色。
6. 可設置是否繪制OSD標簽即標簽文本或圖片和標簽位置。
7. 可設置兩種OSD位置和風格。
8. 可設置是否保存到文件以及文件名。
9. 可直接拖曳文件到ffmpegwidget控件播放。
10. 支持h265視頻流+rtmp等常見視頻流。
11. 可暫停播放和繼續播放。
12. 支持存儲單個視頻文件和定時存儲視頻文件。
13. 自定義頂部懸浮條,發送單擊信號通知,可設置是否啟用。
14. 可設置畫面拉伸填充或者等比例填充。
15. 可設置解碼是速度優先、質量優先、均衡處理。
16. 可對視頻進行截圖(原始圖片)和截屏。
17. 錄像文件存儲支持裸流和MP4文件。
18. 音視頻完美同步,采用外部時鐘同步策略。
19. 支持seek定位播放位置。
20. 支持qsv、dxva2、d3d11va等硬解碼。
21. 支持opengl繪制視頻數據,極低CPU占用。
22. 支持安卓和嵌入式linux,交叉編譯即可。
## 三、效果圖
## 四、相關站點
1. 國內站點:[https://gitee.com/feiyangqingyun/QWidgetDemo](https://gitee.com/feiyangqingyun/QWidgetDemo)
2. 國際站點:[https://github.com/feiyangqingyun/QWidgetDemo](https://github.com/feiyangqingyun/QWidgetDemo)
3. 個人主頁:[https://blog.csdn.net/feiyangqingyun](https://blog.csdn.net/feiyangqingyun)
4. 知乎主頁:[https://www.zhihu.com/people/feiyangqingyun/](https://www.zhihu.com/people/feiyangqingyun/)
5. 體驗地址:[https://blog.csdn.net/feiyangqingyun/article/details/97565652](https://blog.csdn.net/feiyangqingyun/article/details/97565652)
## 五、核心代碼
#include "head.h"#include "frmtab.h"//動態設置權限bool checkPermission(const QString &permission){#ifdef Q_OS_ANDROID#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) QtAndroid::PermissionResult result = QtAndroid::checkPermission(permission); if (result == QtAndroid::PermissionResult::Denied) { QtAndroid::requestPermissionsSync(QStringList() << permission); result = QtAndroid::checkPermission(permission); if (result == QtAndroid::PermissionResult::Denied) { return false; } }#endif#endif return true;}void initStyle(){ //復選框單選框滑塊等指示器大小 QStringList list; int rbtnWidth = 20; int ckWidth = 18; list.append(QString("QRadioButton::indicator{width:%1px;height:%1px;}").arg(rbtnWidth)); list.append(QString("QCheckBox::indicator,QGroupBox::indicator,QTreeWidget::indicator,QListWidget::indicator{width:%1px;height:%1px;}").arg(ckWidth)); QString normalColor = "#E8EDF2"; QString grooveColor = "#1ABC9C"; QString handleColor = "#1ABC9C"; int sliderHeight = 12; int sliderRadius = sliderHeight / 2; int handleWidth = (sliderHeight * 3) / 2 + (sliderHeight / 5); int handleRadius = handleWidth / 2; int handleOffset = handleRadius / 2; list.append(QString("QSlider::horizontal{min-height:%1px;}").arg(sliderHeight * 2)); list.append(QString("QSlider::groove:horizontal{background:%1;height:%2px;border-radius:%3px;}") .arg(normalColor).arg(sliderHeight).arg(sliderRadius)); list.append(QString("QSlider::add-page:horizontal{background:%1;height:%2px;border-radius:%3px;}") .arg(normalColor).arg(sliderHeight).arg(sliderRadius)); list.append(QString("QSlider::sub-page:horizontal{background:%1;height:%2px;border-radius:%3px;}") .arg(grooveColor).arg(sliderHeight).arg(sliderRadius)); list.append(QString("QSlider::handle:horizontal{width:%2px;margin-top:-%3px;margin-bottom:-%3px;border-radius:%4px;" "background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.6 #FFFFFF,stop:0.8 %1);}") .arg(handleColor).arg(handleWidth).arg(handleOffset).arg(handleRadius)); //偏移一個像素 handleWidth = handleWidth + 1; list.append(QString("QSlider::vertical{min-width:%1px;}").arg(sliderHeight * 2)); list.append(QString("QSlider::groove:vertical{background:%1;width:%2px;border-radius:%3px;}") .arg(normalColor).arg(sliderHeight).arg(sliderRadius)); list.append(QString("QSlider::add-page:vertical{background:%1;width:%2px;border-radius:%3px;}") .arg(grooveColor).arg(sliderHeight).arg(sliderRadius)); list.append(QString("QSlider::sub-page:vertical{background:%1;width:%2px;border-radius:%3px;}") .arg(normalColor).arg(sliderHeight).arg(sliderRadius)); list.append(QString("QSlider::handle:vertical{height:%2px;margin-left:-%3px;margin-right:-%3px;border-radius:%4px;" "background:qradialgradient(spread:pad,cx:0.5,cy:0.5,radius:0.5,fx:0.5,fy:0.5,stop:0.6 #FFFFFF,stop:0.8 %1);}") .arg(handleColor).arg(handleWidth).arg(handleOffset).arg(handleRadius)); qApp->setStyleSheet(list.join(""));}int main(int argc, char *argv[]){#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);#endif#if (QT_VERSION > QT_VERSION_CHECK(5,4,0)) //設置opengl模式 AA_UseDesktopOpenGL AA_UseSoftwareOpenGL AA_UseOpenGLES //QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);#endif QApplication a(argc, argv); App::setFont(); App::setCode(); App::ConfigFile = AppPath + "/video_ffmpeg.ini"; App::readConfig(); frmTab w;#ifdef Q_OS_ANDROID //請求權限 checkPermission("android.permission.READ_EXTERNAL_STORAGE"); checkPermission("android.permission.WRITE_EXTERNAL_STORAGE"); QString strDir = AppPath + "/snap"; QDir dir(strDir); if (!dir.exists()) { dir.mkpath(strDir); } initStyle(); w.showMaximized();#else w.resize(1100, 700); w.setWindowTitle(QString("qt+ffmpeg 示例 %1 %2").arg(App::Version).arg(App::TitleFlag)); w.show(); App::setFormInCenter(&w);#endif return a.exec();} 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的DS1819 对应版本的FFMPEG_Qt音视频开发33-ffmpeg安卓版的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PPT怎么在剪映_剪映怎么剪辑音乐?添加
- 下一篇: com组件 安全提示_【加粉利器】百度基