2031 lines
61 KiB
C++
2031 lines
61 KiB
C++
#include "rm_video_list.h"
|
|
#include <qdir.h>
|
|
|
|
|
|
#include <qapplication.h>
|
|
#include <QUrl>
|
|
#include <QRegularExpression>
|
|
|
|
//#include "rm_uimanager.h"
|
|
#include "rm_video_item_2ch.h"
|
|
#include "../ui/rm_dialog_progress.h"
|
|
//#include "../widgets/rm_toolbutton.h"
|
|
#include "../core/rm_play_process.h"
|
|
#include "rm_overwrite.h"
|
|
|
|
#if (DETECT_USB_CHANGE)
|
|
#include "../core/rm_usb.h"
|
|
#endif
|
|
|
|
#include <QDataStream>
|
|
#include <QStringList>
|
|
|
|
#if (RM_MODEL == RM_MODEL_TYPE_AN6000)
|
|
#include "../data/an6000_decode.h"
|
|
#endif
|
|
|
|
#if (SUPPORT_AVI_FIX_DURL)
|
|
#include "rm_avirepair.h"
|
|
#endif
|
|
|
|
#if (PLAYER_ONLY_LIBRARY_MODE)
|
|
RMVideoFileList* RMVideoFileList::_instance = NULL;
|
|
#endif // PLAYER_ONLY_LIBRARY_MODE
|
|
|
|
// SORT
|
|
#if !(USE_1HOUR_FILTER)
|
|
bool RMVideoItemCompare(RMVideoItem * s1 , RMVideoItem * s2)
|
|
{
|
|
// 동일할 경우 상시 먼저 ..
|
|
if(s1->startTime() == s2->startTime())
|
|
{
|
|
return (int)s1->type < (int)s2->type;
|
|
}
|
|
return s1->startTime() < s2->startTime();
|
|
}
|
|
#else // #if !(USE_1HOUR_FILTER)
|
|
bool RMVideoItemCompare(RMVideoItem * s1 , RMVideoItem * s2)
|
|
{
|
|
// 2022/07/12 역순으로 변경
|
|
return RMVideoFileList::instance()->bSortDsc ? s2->startTime() < s1->startTime() : s1->startTime() < s2->startTime();
|
|
}
|
|
#endif #if !(USE_1HOUR_FILTER)
|
|
|
|
int RMVideoFileList::n_lastPercent = -1;
|
|
|
|
#if (FILE_FORMAT_MOV && FILE_FORMAT_AVI)
|
|
QList<QString> RMVideoFileList::fileFilters = QList<QString>() << QString("*.AVI") << QString("*.MOV") << QString("*.MP4");
|
|
#elif (FILE_FORMAT_AVI)
|
|
QList<QString> RMVideoFileList::fileFilters = QList<QString>() << QString("*.AVI");
|
|
#elif (FILE_FORMAT_MOV)
|
|
#if (USE_FFMPEG_PW)
|
|
#if (SUPPORT_MP4TB4)
|
|
QList<QString> RMVideoFileList::fileFilters = QList<QString>() << QString("*.TB4") << QString("*.MP4");
|
|
#else // SUPPORT_MP4TB4
|
|
QList<QString> RMVideoFileList::fileFilters = QList<QString>() << QString("*.TB4");// << QString("*.MP4");
|
|
#endif // SUPPORT_MP4TB4
|
|
#else // USE_FFMPEG_PW
|
|
QList<QString> RMVideoFileList::fileFilters = QList<QString>() << QString("*.MOV") << QString("*.MP4");
|
|
#endif // USE_FFMPEG_PW
|
|
#endif
|
|
|
|
RMVideoFileList::RMVideoFileList(QObject* parent) : QObject(parent)
|
|
{
|
|
_filter = FILTER_NORMAL | FILTER_EVENT;
|
|
_playItem = NULL;
|
|
|
|
#if (USE_1HOUR_FILTER)
|
|
b1HourList = true; // 1시간 단위 리스트
|
|
bSortDsc = true; // (기본값) 표시=최신순으로 정렬, 시간순으로 정렬
|
|
#endif // USE_1HOUR_FILTER
|
|
|
|
#if (SUPPORT_LOADING_CANCEL)
|
|
bCancelLoading = false; // 로딩 취소
|
|
#endif
|
|
}
|
|
// 모델별 채널 처리
|
|
#if !(RECURSIVE_APPEND_FILE)
|
|
void RMVideoFileList::_appendFrontRear(QString& folder,QList<QUrl>& list)
|
|
{
|
|
// 신규 모델 처리시 ELSE 를 사용하지 않는다
|
|
#if (RM_MODEL == RM_MODEL_TYPE_NX_DRW22)
|
|
const QList<QString> folders = QList<QString>() << "F" << "R";
|
|
#elif (RM_MODEL == RM_MODEL_TYPE_ADT_CAPS)
|
|
const QList<QString> folders = QList<QString>() << "1" << "2";
|
|
#endif
|
|
foreach (QString each_folder, folders)
|
|
{
|
|
QString current_front = QDir::cleanPath(folder + PATH_COMPONENT + each_folder);
|
|
if(QFile::exists(current_front))
|
|
{
|
|
QDir fdir(current_front);
|
|
|
|
fdir.setNameFilters(RMVideoFileList::fileFilters); // 확장자 필터
|
|
QStringList allFiles = fdir.entryList();
|
|
foreach (const QString &str, allFiles)
|
|
{
|
|
if(str == "." || str == "..")
|
|
{
|
|
continue;
|
|
}
|
|
|
|
QDateTime dateTime;
|
|
QString filePath = QDir::cleanPath(current_front + PATH_COMPONENT + str);
|
|
|
|
// static 이라 일단 중복되어도 추가함.
|
|
if( RMVideoItem::IsFeasible(filePath,&dateTime) != (int)TYPE_UNDEFINED)
|
|
{
|
|
list.append(QUrl::fromLocalFile(filePath));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif // #if !(RECURSIVE_APPEND_FILE)
|
|
#if (RM_MODEL == RM_MODEL_TYPE_AN6000)
|
|
void RMVideoFileList::removeTemps()
|
|
{
|
|
for(int i=0;i<_items.size();i++){
|
|
_items.at(i)->removeTemp();
|
|
}
|
|
}
|
|
#endif //
|
|
bool RMVideoFileList::addItem(QString filePath,QDateTime* pDateTime,GROUP_TYPE type)
|
|
{
|
|
QString cleanPath = QDir::cleanPath(filePath);
|
|
|
|
#if (TRI_CHANNEL || PENTA_CHANNEL)
|
|
int ch = 1;
|
|
RMVideoFileList::_checkChannelInfo(filePath,&ch);
|
|
#else // TRI_CHANNEL
|
|
#if (FORCE_2CH || SINGLE_CH_VIEWER)
|
|
bool isCH2 = false;
|
|
#else // !FORCE_2CH
|
|
bool isCH2 = false;
|
|
#if (SUPPORT_2CH)
|
|
bool is2CH = false; // 1FILE 2CH 영상
|
|
RMVideoFileList::_checkChannelInfo(filePath,&isCH2,&is2CH);
|
|
#else // SUPPORT_2CH
|
|
RMVideoFileList::_checkChannelInfo(filePath,&isCH2);
|
|
#endif // SUPPORT_2CH
|
|
#endif // FORCE_2CH
|
|
#endif // TRI_CHANNEL
|
|
|
|
// 무조건 중복체크 해야함
|
|
if(itemExist(cleanPath) == true)
|
|
{
|
|
//qInfo() << "exist skip:" << cleanPath << __FUNCTION__;
|
|
return false;
|
|
}
|
|
|
|
#if (SUPPORT_AVI_FIX_DURL)
|
|
// 복구 필요
|
|
if(cleanPath.endsWith("_EXIT.AVI",Qt::CaseInsensitive)) {
|
|
QString destPath;
|
|
if (RMAVIRepair::repairV50(filePath,destPath) == true)
|
|
{
|
|
if(destPath.isEmpty() == false) // true 일 경우 복구할 필요 없음
|
|
{
|
|
cleanPath = destPath;
|
|
}
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if (TRI_CHANNEL || PENTA_CHANNEL)
|
|
RMVideoItem* item = new RMVideoItem(cleanPath,ch,pDateTime);
|
|
#else
|
|
RMVideoItem* item = new RMVideoItem(cleanPath,isCH2,pDateTime);
|
|
#endif
|
|
if(item->isValid() == true)
|
|
{
|
|
item->type = type;
|
|
item->dropItem = true;
|
|
|
|
// 전방, 또는 후방 파일 확인해서 추가
|
|
#if !(FORCE_2CH || SINGLE_CH_VIEWER)
|
|
if(_addOtherChannelFile(item))
|
|
{
|
|
#if (CHECK_REAR_DURATION) // 후방도 재생시간 확인하여 제거
|
|
if(item->isRearDuration() == false) {
|
|
delete item;
|
|
item = NULL;
|
|
}
|
|
#endif // CHECK_REAR_DURATION
|
|
}
|
|
#endif // FORCE_2CH
|
|
|
|
#if (CHECK_VIDEO_BITRATE)
|
|
item->testBitrate2CH();
|
|
|
|
// 후방 파일만 존재하는 경우 후방 파일의 bitrate 가 < 미만일 경우
|
|
if(item->anyFilePath().length() == 0) {
|
|
delete item;
|
|
item = NULL;
|
|
}
|
|
#endif
|
|
|
|
#if (SUPPORT_2CH)
|
|
if(is2CH) {
|
|
item->filePathCH2 = item->filePath;
|
|
}
|
|
#endif // SUPPORT_2CH
|
|
|
|
if(item != NULL) {
|
|
_items.append(item);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
delete item;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
void RMVideoFileList::checkedItems(QList<RMVideoItem*>& items)
|
|
{
|
|
foreach (RMVideoItem* item, filteredItems()) {
|
|
#if (SINGLE_SAVE_CHECK_FILE)
|
|
if(item->checked) { // 선택된 파일이 존재할 경우 1개만 리턴
|
|
items.append(item);
|
|
return;
|
|
}
|
|
#else // SINGLE_SAVE_CHECK_FILE
|
|
#if (SINGLE_SAVE_FILE)
|
|
if(item == _playItem) {
|
|
items.append(item);
|
|
}
|
|
#else
|
|
if(item->checked) {
|
|
items.append(item);
|
|
}
|
|
#endif
|
|
#endif // SINGLE_SAVE_CHECK_FILE
|
|
}
|
|
#if (SINGLE_SAVE_CHECK_FILE)
|
|
// 선택된 파일이 없을 경우 재생중인
|
|
foreach (RMVideoItem* item, filteredItems()) {
|
|
if(item == _playItem) {
|
|
item->checked = true;
|
|
items.append(item);
|
|
}
|
|
}
|
|
#endif // SINGLE_SAVE_CHECK_FILE
|
|
}
|
|
RMVideoItem* RMVideoFileList::searchPlayItem(QString prefix)
|
|
{
|
|
foreach (RMVideoItem* item, filteredItems()) {
|
|
//qInfo() << item->fileName << prefix << __FUNCTION__;
|
|
if(item->fileName.startsWith(prefix)) {
|
|
return item;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
void RMVideoFileList::_backupOverwrite(QString target,QString src,int countLeft)
|
|
{
|
|
bool bCopy = true;
|
|
if(QFile::exists(target)) {
|
|
|
|
// 확인 처리 해야할 경우
|
|
if (RMOverwrite::check(OVERWRITE_OPTION_ASK))
|
|
{
|
|
QFileInfo info(target);
|
|
QString baseName = info.baseName();
|
|
#if (0)
|
|
// 파일 인덱스 존재할 경우 제거
|
|
// NNF_191125-092637-003801_2
|
|
QStringList ls = baseName.split("-",QString::SkipEmptyParts);
|
|
if(ls.length() == 3)
|
|
{
|
|
ls.removeLast();
|
|
}
|
|
baseName = ls.join("-");
|
|
#endif //
|
|
RMOverwrite::currentFileName = baseName + "." + info.suffix();
|
|
RMOverwrite::currentCount = countLeft;
|
|
emit backupPaused(true);
|
|
RMOverwrite::lock();
|
|
RMOverwrite::wait();
|
|
RMOverwrite::unlock();
|
|
|
|
|
|
emit backupPaused(false);
|
|
|
|
// 작업 취소
|
|
if(RMOverwrite::check(OVERWRITE_OPTION_CANCEL)) {
|
|
return;
|
|
}
|
|
}
|
|
// 확인 처리 후..
|
|
if (RMOverwrite::check(OVERWRITE_OPTION_SKIP)) {
|
|
bCopy = false;
|
|
}
|
|
else if (RMOverwrite::check(OVERWRITE_OPTION_WRITE)) {
|
|
bCopy = true;
|
|
//qInfo() << "remove:" << target;
|
|
QFile::remove(target);
|
|
}
|
|
|
|
// // 전체가 아닐 경우 다시 ASK 로 변경
|
|
// if(RMOverwrite::check(OVERWRITE_OPTION_ALL) == false) {
|
|
// RMOverwrite::gCurrent = OVERWRITE_OPTION_ASK;
|
|
// }
|
|
|
|
}
|
|
if(bCopy) {
|
|
QFile::copy(src,target);
|
|
#if (RM_MODEL == RM_MODEL_TYPE_AN6000) // 디코딩
|
|
if(is_encrypted_an6000(target.toStdWString().c_str())) {
|
|
decrypt_an6000(target.toStdWString().c_str());
|
|
}
|
|
#endif //
|
|
}
|
|
}
|
|
void RMVideoFileList::backup(QString dest)
|
|
{
|
|
QList<RMVideoItem*> items;
|
|
checkedItems(items);
|
|
if(items.isEmpty()){
|
|
return;
|
|
}
|
|
|
|
RMOverwrite::reset(); // 초기화
|
|
|
|
emit backupStarted();
|
|
QCoreApplication::processEvents();
|
|
QThread::msleep(1);
|
|
|
|
RMVideoFileList::n_lastPercent = -1;
|
|
int index = 0;
|
|
int count = items.count();
|
|
//qInfo() << __FUNCTION__;
|
|
foreach (RMVideoItem* item, items) {
|
|
|
|
#if (SINGLE_SAVE_FILE && !SINGLE_SAVE_CHECK_FILE)
|
|
if(item != _playItem) {
|
|
continue;
|
|
}
|
|
qInfo() << __FUNCTION__ << item->anyFilePath();
|
|
#else
|
|
if(item->checked == false) {
|
|
continue;
|
|
}
|
|
#endif
|
|
if(item->filePath.isEmpty() == false)
|
|
{
|
|
QFileInfo info(item->filePath);
|
|
QString target = QDir::cleanPath(dest + QDir::separator() + info.baseName() + "." + info.suffix());
|
|
_backupOverwrite(target,item->filePath,items.count() - index);
|
|
|
|
// 취소
|
|
if(RMOverwrite::check(OVERWRITE_OPTION_CANCEL)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
#if !(DUAL_CH_FILE || SINGLE_CH_VIEWER)
|
|
if(item->filePathCH2.isEmpty() == false)
|
|
{
|
|
QFileInfo info(item->filePathCH2);
|
|
QString target = QDir::cleanPath(dest + QDir::separator() + info.baseName() + "." + info.suffix()).toUpper();
|
|
_backupOverwrite(target,item->filePathCH2,items.count() - index);
|
|
|
|
// 취소
|
|
if(RMOverwrite::check(OVERWRITE_OPTION_CANCEL)) {
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if (PENTA_CHANNEL)
|
|
if(item->filePathCH3.isEmpty() == false)
|
|
{
|
|
QFileInfo info(item->filePathCH3);
|
|
QString target = QDir::cleanPath(dest + QDir::separator() + info.baseName() + "." + info.suffix()).toUpper();
|
|
_backupOverwrite(target,item->filePathCH3,items.count() - index);
|
|
|
|
// 취소
|
|
if(RMOverwrite::check(OVERWRITE_OPTION_CANCEL)) {
|
|
break;
|
|
}
|
|
}
|
|
if(item->filePathCH4.isEmpty() == false)
|
|
{
|
|
QFileInfo info(item->filePathCH4);
|
|
QString target = QDir::cleanPath(dest + QDir::separator() + info.baseName() + "." + info.suffix()).toUpper();
|
|
_backupOverwrite(target,item->filePathCH4,items.count() - index);
|
|
|
|
// 취소
|
|
if(RMOverwrite::check(OVERWRITE_OPTION_CANCEL)) {
|
|
break;
|
|
}
|
|
}
|
|
if(item->filePathCH5.isEmpty() == false)
|
|
{
|
|
QFileInfo info(item->filePathCH5);
|
|
QString target = QDir::cleanPath(dest + QDir::separator() + info.baseName() + "." + info.suffix()).toUpper();
|
|
_backupOverwrite(target,item->filePathCH5,items.count() - index);
|
|
|
|
// 취소
|
|
if(RMOverwrite::check(OVERWRITE_OPTION_CANCEL)) {
|
|
break;
|
|
}
|
|
}
|
|
#endif // PENTA_CHANNEL
|
|
|
|
// 중복 처리 선택 옵션에서 전체가 아닐 경우 다시 ASK 로 변경
|
|
if(RMOverwrite::check(OVERWRITE_OPTION_ALL) == false) {
|
|
RMOverwrite::gCurrent = OVERWRITE_OPTION_ASK;
|
|
}
|
|
|
|
|
|
int percent = (int)(((double)++index) / ((double)count) * (double)(PROGRESS_BAR_MAX));
|
|
LOG_INFO << "backup:" << item->anyFilePath() << " percent:" << percent;
|
|
if(percent != RMVideoFileList::n_lastPercent)
|
|
{
|
|
RMVideoFileList::n_lastPercent = percent;
|
|
emit updateProgress(percent);
|
|
QCoreApplication::processEvents();
|
|
QThread::usleep(1);
|
|
// unsigned long nSleep = (RMVideoFileList::n_lastPercent == -1) ? 100 : 5;
|
|
}
|
|
}
|
|
emit backupEnd();
|
|
}
|
|
|
|
//! \brief 리스트 삭제하고 이벤트 전달
|
|
void RMVideoFileList::clearList()
|
|
{
|
|
emit listUpdateStarted(true);
|
|
|
|
#if (RM_MODEL == RM_MODEL_TYPE_TBD360 || RM_MODEL_EMT_KR) // RM_MODEL == RM_MODEL_TYPE_XLDR_88 ||
|
|
_filter = FILTER_NORMAL;
|
|
#else // RM_MODEL_TYPE_TBD360
|
|
_filter = FILTER_ALL;
|
|
#endif // RM_MODEL_TYPE_TBD360
|
|
_items.clear();
|
|
QCoreApplication::processEvents();
|
|
|
|
#if (USE_1HOUR_FILTER)
|
|
set1HourList(b1HourList,false,NULL); // 정렬에 따른 1시간 필터 처리
|
|
#else // USE_1HOUR_FILTER
|
|
// _filtered Item 처리
|
|
_updateItemsByFilter();
|
|
#endif // #if (USE_1HOUR_FILTER)
|
|
|
|
#if (USE_1HOUR_FILTER)
|
|
count1HourItems();
|
|
#endif
|
|
|
|
QCoreApplication::processEvents();
|
|
QThread::usleep(1);
|
|
emit listUpdateEnd(true,NULL);
|
|
emit loadListEnd();
|
|
}
|
|
void RMVideoFileList::loadFromList(QList<QUrl> list,bool bPlayFirstAdded)
|
|
{
|
|
Q_UNUSED(bPlayFirstAdded)
|
|
emit listUpdateStarted(true);
|
|
#if (SUPPORT_LOADING_CANCEL)
|
|
bCancelLoading = false;
|
|
#endif // #if (SUPPORT_LOADING_CANCEL)
|
|
|
|
if(list.isEmpty()) {
|
|
#if (USE_1HOUR_FILTER)
|
|
count1HourItems();
|
|
#endif
|
|
emit listUpdateEnd(true,NULL);
|
|
return;
|
|
}
|
|
#if (RM_MODEL == RM_MODEL_TYPE_TBD360 || RM_MODEL_EMT_KR) // RM_MODEL_EMT_KR = 실제로는 maxType 선택됨
|
|
_filter = FILTER_NORMAL;
|
|
#else // RM_MODEL_TYPE_TBD360
|
|
_filter = FILTER_ALL;
|
|
#endif // RM_MODEL_TYPE_TBD360
|
|
_items.clear();
|
|
QCoreApplication::processEvents();
|
|
|
|
RMVideoFileList::n_lastPercent = -1;
|
|
int index = 0;
|
|
int count = list.count();
|
|
|
|
#if (DETECT_USB_CHANGE)
|
|
// 경로가 USB 일 경우 드라이버 지정
|
|
QString path = list.first().toLocalFile();
|
|
RMApp::instance()->usb->setOpenDriveWithPath(path);
|
|
//((WindowMain*)RMApp::instance()->pMainWindow)->_usb->setOpenDriveWithFolder();
|
|
#endif // DETECT_USB_CHANGE
|
|
|
|
foreach (const QUrl &url, list)
|
|
{
|
|
int percent = (int)(((double)++index) / ((double)count) * (double)(PROGRESS_BAR_MAX));
|
|
if(percent % 2 == 0 && percent != RMVideoFileList::n_lastPercent)
|
|
{
|
|
RMVideoFileList::n_lastPercent = percent;
|
|
emit updateProgress(percent);
|
|
// SLEEP 기능 제거하면 썸네일 표시안됨???
|
|
//QThread::usleep(1);
|
|
//QCoreApplication::processEvents();
|
|
}
|
|
|
|
QString fileName = url.toLocalFile();
|
|
QDateTime dateTime;
|
|
RMVideoFileList::GROUP_TYPE type = ( RMVideoFileList::GROUP_TYPE)RMVideoItem::IsFeasible(fileName,&dateTime);
|
|
if(type == RMVideoFileList::TYPE_UNDEFINED)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(addItem(fileName,&dateTime,type) == true) // 경로에 / \ 가 동시에 들어가면 안됨..
|
|
{
|
|
}
|
|
|
|
#if (SUPPORT_LOADING_CANCEL)
|
|
if(bCancelLoading) {
|
|
break;
|
|
}
|
|
#endif // #if (SUPPORT_LOADING_CANCEL)
|
|
|
|
}
|
|
#if (USE_1HOUR_FILTER)
|
|
setSortList(bSortDsc); // 정렬처리
|
|
set1HourList(b1HourList,false,NULL); // 정렬에 따른 1시간 필터 처리
|
|
#else // USE_1HOUR_FILTER
|
|
qSort(_items.begin(),_items.end(),RMVideoItemCompare);
|
|
|
|
#if (RM_MODEL_EMT_KR)
|
|
// 로딩된 파일 중 가장 많은 파일이 존재하는 녹화타입 선택
|
|
selectMaxCountFilter();
|
|
#endif // RM_MODEL_EMT_KR
|
|
|
|
// _filtered Item 처리
|
|
_updateItemsByFilter();
|
|
#endif // #if (USE_1HOUR_FILTER)
|
|
|
|
#if (USE_1HOUR_FILTER)
|
|
count1HourItems();
|
|
#endif
|
|
|
|
QCoreApplication::processEvents();
|
|
QThread::usleep(1);
|
|
emit listUpdateEnd(true,NULL);
|
|
|
|
#if (PLAY_FIRST_LOADED)
|
|
int old = getPlayIndex();
|
|
// TELEBIT 는 간편/전체 리스트 검색 (현재 리스트와 동일하지 않을 수 있음)
|
|
if(_filteredItems.count() > 0)
|
|
{
|
|
emit playItemFound(_filteredItems.first(),old);
|
|
}
|
|
#endif
|
|
|
|
emit loadListEnd();
|
|
}
|
|
#if (RM_MODEL_EMT_KR)
|
|
int RMVideoFileList::currentFilterIndex()
|
|
{
|
|
QList<FILTER> filters = QList<FILTER>() << FILTER_NORMAL << FILTER_EVENT << FILTER_PARK << FILTER_PARK_EVENT << FILTER_MANUAL << FILTER_MYBOX;
|
|
for(int i=0;i<filters.size();i++) {
|
|
//qInfo() << "currentFilterIndex:" << filters[i] << _filter << __FUNCTION__;
|
|
if(filters[i] == _filter) {
|
|
return i;
|
|
}
|
|
}
|
|
qInfo() << "currentFilterIndex:0" << __FUNCTION__;
|
|
return 0;
|
|
}
|
|
void RMVideoFileList::selectMaxCountFilter()
|
|
{
|
|
// 각 타입별 개수 확인
|
|
int filterCount[10] = {0,};
|
|
foreach (RMVideoItem* item, _items) {
|
|
if(item->type == RMVideoFileList::TYPE_UNDEFINED) {
|
|
continue;
|
|
}
|
|
filterCount[item->type] += 1;
|
|
}
|
|
int maxType = 0;
|
|
int maxCount = 0;
|
|
for(int i=0;i<10;i++) {
|
|
if(filterCount[i] > maxCount) {
|
|
maxCount = filterCount[i];
|
|
maxType = i;
|
|
}
|
|
}
|
|
_filter = filterTypeFromGroupType((GROUP_TYPE)maxType);
|
|
//qInfo() << "MAX TYPE:" << _filter << __FUNCTION__;
|
|
}
|
|
#endif // RM_MODEL_EMT_KR
|
|
|
|
#ifdef _DEBUG
|
|
void RMVideoFileList::print()
|
|
{
|
|
foreach (RMVideoItem* item, _items) {
|
|
item->print();
|
|
}
|
|
}
|
|
#endif
|
|
RMVideoFileList::GROUP_TYPE RMVideoFileList::checkGroupTypeFromFolderPath(QString folderPath)
|
|
{
|
|
QStringList parts = folderPath.split(PATH_COMPONENT);
|
|
QString name = parts.last();
|
|
name = name.toUpper();
|
|
// 모델은 폴더만으로 파일 종류 구분 불가
|
|
if(name.contains("Event",Qt::CaseInsensitive) == true)
|
|
{
|
|
return TYPE_EVENT;
|
|
}
|
|
else if(name.contains("Normal",Qt::CaseInsensitive) == true) // 상시
|
|
{
|
|
return TYPE_NORMAL;
|
|
}
|
|
return TYPE_UNDEFINED;
|
|
}
|
|
bool RMVideoFileList::isRootPath(QString folderPath)
|
|
{
|
|
QDir dir(folderPath);
|
|
dir.setFilter(QDir::Dirs);
|
|
|
|
QStringList allDirs = dir.entryList();
|
|
foreach (const QString &str, allDirs)
|
|
{
|
|
if(str == "." || str == "..")
|
|
{
|
|
continue;
|
|
}
|
|
QString eachFolderPath = folderPath + PATH_COMPONENT + str;
|
|
|
|
if(RMVideoFileList::checkGroupTypeFromFolderPath(eachFolderPath) != RMVideoFileList::TYPE_UNDEFINED)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
#if (RECURSIVE_APPEND_FILE)
|
|
void RMVideoFileList::appendFolderToList(QString folderPath,QList<QUrl>& list,int depth)
|
|
{
|
|
if(RECURSIVE_FOLDER_MAX_DEPTH > depth) {
|
|
QDir dir(folderPath);
|
|
dir.setFilter(QDir::Dirs);
|
|
foreach (const QString& eachFolder, dir.entryList()) {
|
|
|
|
if(eachFolder == "." || eachFolder == "..")
|
|
{
|
|
continue;
|
|
}
|
|
// 폴더는 탐색
|
|
QString fullPath = QDir::cleanPath(folderPath + PATH_COMPONENT + eachFolder);
|
|
RMVideoFileList::appendFolderToList(fullPath,list,depth+1);
|
|
}
|
|
} else {
|
|
//qInfo() << "SKIP:" << folderPath;
|
|
}
|
|
|
|
QDir dirFile(folderPath);
|
|
dirFile.setNameFilters(RMVideoFileList::fileFilters);
|
|
QStringList allFiles = dirFile.entryList();
|
|
foreach (const QString& eachFile, allFiles) {
|
|
QDateTime dateTime;
|
|
QString fullPath = QDir::cleanPath(folderPath + PATH_COMPONENT + eachFile);
|
|
|
|
// static 이라 일단 중복되어도 추가함.
|
|
if( RMVideoItem::IsFeasible(fullPath,&dateTime) != (int)TYPE_UNDEFINED)
|
|
{
|
|
list.append(QUrl::fromLocalFile(fullPath));
|
|
}
|
|
}
|
|
|
|
}
|
|
#else
|
|
void RMVideoFileList::appendToList(QString folderPath,QList<QUrl>& list, bool baseFolderOnly)
|
|
{
|
|
if(baseFolderOnly == true)
|
|
{
|
|
RMVideoFileList::GROUP_TYPE type = RMVideoFileList::checkGroupTypeFromFolderPath(folderPath);
|
|
if(type == TYPE_UNDEFINED)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
QDir dir(folderPath);
|
|
dir.setNameFilters(RMVideoFileList::fileFilters);
|
|
QStringList allFiles = dir.entryList();
|
|
|
|
foreach (const QString &str, allFiles)
|
|
{
|
|
QDateTime dateTime;
|
|
QString filePath = QDir::cleanPath(folderPath + PATH_COMPONENT + str);
|
|
|
|
// static 이라 일단 중복되어도 추가함.
|
|
if( RMVideoItem::IsFeasible(filePath,&dateTime) != (int)TYPE_UNDEFINED)
|
|
{
|
|
list.append(QUrl::fromLocalFile(filePath));
|
|
}
|
|
else
|
|
{
|
|
//qInfo() << "NO FEASIBLE" << filePath;
|
|
}
|
|
}
|
|
|
|
// Front, Rear 폴더 탐색
|
|
_appendFrontRear(folderPath,list);
|
|
}
|
|
void RMVideoFileList::appendFolderToList(QString rootFolderPath,QList<QUrl>& list)
|
|
{
|
|
QDir dir(rootFolderPath);
|
|
dir.setFilter(QDir::Dirs);
|
|
|
|
QStringList allDirs = dir.entryList();
|
|
|
|
// 자체 폴더도 추가
|
|
RMVideoFileList::appendToList(rootFolderPath,list,false);
|
|
|
|
foreach (const QString &str, allDirs)
|
|
{
|
|
if(str == "." || str == "..")
|
|
{
|
|
continue;
|
|
}
|
|
QString eachFolderPath = QDir::cleanPath(rootFolderPath + PATH_COMPONENT + str);
|
|
//qInfo() << "appendToList check:" << eachFolderPath;
|
|
|
|
if(RMVideoFileList::checkGroupTypeFromFolderPath(eachFolderPath) != RMVideoFileList::TYPE_UNDEFINED)
|
|
{
|
|
//qInfo() << "appendToList" << eachFolderPath;
|
|
RMVideoFileList::appendToList(eachFolderPath,list,true); // root 에서 처리하면 기본 폴더만 추가
|
|
}
|
|
// 채널 폴더 (EVENT 등 폴더 내부에서 열기)
|
|
else if (str == QString("1") || str == QString("2")) {
|
|
RMVideoFileList::appendToList(eachFolderPath,list,false);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
bool RMVideoFileList::_searchItem(bool next, RMVideoItem** item,int fromIndex)
|
|
{
|
|
*item = NULL;
|
|
if(fromIndex == -1 && _playItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
QList<RMVideoItem*>& items = filteredItems();
|
|
|
|
int offset = next ? 1 : -1; // next, previous
|
|
int index = fromIndex == -1 ? (items.indexOf(_playItem) + offset) : (fromIndex + offset);
|
|
#if (RM_MODEL_EMT_KR)
|
|
if(index < -1) {
|
|
#else
|
|
if(index < 0) {
|
|
#endif
|
|
return false;
|
|
}
|
|
else if (next == true && index >= items.count()) {
|
|
#if (PROFILE_VIDEO_FILE_LOADING)
|
|
LOG_VLOAD << "VIDEO LIST PLAY PROFILE DONE" << LOG_VLOAD_T2;
|
|
// 1회만 반복함
|
|
return false;
|
|
#endif
|
|
index = 0;
|
|
}
|
|
#if (RM_MODEL_EMT_KR)
|
|
else if (index < 0) {
|
|
index = items.size() - 1;
|
|
}
|
|
#endif
|
|
*item = items.at(index);
|
|
return true;
|
|
|
|
}
|
|
RMVideoItem* RMVideoFileList::nexItem(bool bNext)
|
|
{
|
|
RMVideoItem* item = NULL;
|
|
if(_playItem != NULL && _searchItem(bNext,&item,getPlayIndex()))
|
|
{
|
|
return item;
|
|
}
|
|
return NULL;
|
|
}
|
|
bool RMVideoFileList::isNextPlayItemExist(bool bNext)
|
|
{
|
|
if(_playItem == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
RMVideoItem* item = NULL;
|
|
return _searchItem(bNext,&item,getPlayIndex());
|
|
}
|
|
RMVideoItem* RMVideoFileList::itemWithPath(QString filePath)
|
|
{
|
|
#if (FORCE_2CH || SINGLE_CH_VIEWER)
|
|
QString search = QFileInfo(filePath).baseName();
|
|
#else
|
|
QString search = RMVideoItem::fileNameWithoutChannel(filePath);
|
|
#endif
|
|
foreach (RMVideoItem* item, _items)
|
|
{
|
|
#if (FORCE_2CH || SINGLE_CH_VIEWER)
|
|
QString compare = QFileInfo(item->anyFilePath()).baseName();
|
|
#else
|
|
QString compare = RMVideoItem::fileNameWithoutChannel(item->anyFilePath());
|
|
#endif
|
|
if(search.compare(compare,Qt::CaseInsensitive) == 0) {
|
|
return item;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
void RMVideoFileList::playItem(RMVideoItem* item)
|
|
{
|
|
if(item != NULL) {
|
|
int old = getPlayIndex();
|
|
emit playItemFound(item,old);
|
|
}
|
|
}
|
|
void RMVideoFileList::onPlayNextVideo(int fromIndex)
|
|
{
|
|
#if (FFMPEG_VTHREAD_DEBUG)
|
|
emit playNoMoreItem(); // 더이상 플레이할 아이템 없음
|
|
return;
|
|
#endif // 연속재생 방지
|
|
//qInfo() << "onPlayNextVideo:" << fromIndex;
|
|
if((fromIndex == -1 && _playItem == NULL) || RMPlayProcess::bProcessing)
|
|
{
|
|
return;
|
|
}
|
|
int old = getPlayIndex();
|
|
//qInfo() << "onPlayNextVideo old index:" << old;
|
|
RMVideoItem* item = NULL;
|
|
if(_searchItem(true,&item,fromIndex) == true) // 탐색
|
|
{
|
|
emit playItemFound(item,old); // 탐색완료 -> 다음파일
|
|
}
|
|
else
|
|
{
|
|
emit playNoMoreItem(); // 더이상 플레이할 아이템 없음
|
|
}
|
|
}
|
|
void RMVideoFileList::onPlayPreviousVideo(int fromIndex)
|
|
{
|
|
if((fromIndex == -1 && _playItem == NULL) || RMPlayProcess::bProcessing)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int old = getPlayIndex();
|
|
|
|
RMVideoItem* item = NULL;
|
|
if(_searchItem(false,&item,fromIndex) == true) // 탐색
|
|
{
|
|
emit playItemFound(item,old); // 탐색완료
|
|
}
|
|
else
|
|
{
|
|
emit playNoMoreItem(); // 더이상 플레이할 아이템 없음
|
|
}
|
|
}
|
|
#if (USE_DATE_TIME_LIST)
|
|
QDate RMVideoFileList::getFirstDate()
|
|
{
|
|
if(_items.isEmpty()) {
|
|
return QDate();
|
|
}
|
|
return _items.first()->startTime().date();
|
|
}
|
|
void RMVideoFileList::getMonthList(int year, int month, QSet<int>& ret, QList<RMVideoItem*>& dayItems)
|
|
{
|
|
dayItems.clear();
|
|
ret.clear();
|
|
// 이전달 마지막일
|
|
QDate after = QDate(year,month,1).addDays(-1);
|
|
|
|
// 다음달 1일
|
|
QDate before = QDate(year,month,1).addMonths(1);
|
|
for(int i=0;i<_items.size();i++) {
|
|
QDate st = _items.at(i)->startTime().date();
|
|
if(st > after && st < before) {
|
|
dayItems.append(_items.at(i)); // 해당일자 아이템 추가
|
|
ret.insert(st.day()); // 날짜 추가
|
|
}
|
|
}
|
|
}
|
|
#endif// USE_DATE_TIME_LIST
|
|
int RMVideoFileList::removeItem(RMVideoItem* item)
|
|
{
|
|
// 필터된 아이템의 인덱스를 리턴한다
|
|
int index = _filteredItems.indexOf(item);
|
|
_filteredItems.removeAt(index);
|
|
|
|
// 전체 아이템에서도 제거
|
|
_items.removeOne(item);
|
|
|
|
return index;
|
|
}
|
|
#if (USE_1HOUR_FILTER)
|
|
RMVideoItem* RMVideoFileList::findFirstItemIn1Hour(RMVideoItem* searchItem)
|
|
{
|
|
if(searchItem == NULL) {
|
|
return NULL;
|
|
}
|
|
// 최신순으로 표시할 경우
|
|
//
|
|
QDateTime fromDateTime = simpleFromDateTime(searchItem->startTime());
|
|
foreach (RMVideoItem* item, _items)
|
|
{
|
|
if(bSortDsc) {
|
|
int secsTo = item->startTime().secsTo(fromDateTime);
|
|
if (secsTo > 0 && secsTo < 3600)
|
|
{
|
|
return item;
|
|
}
|
|
} else {
|
|
if (item->startTime().secsTo(fromDateTime) <= 0 )
|
|
{
|
|
return item;
|
|
}
|
|
}
|
|
}
|
|
return NULL; // 발생할 수 없음..
|
|
}
|
|
QDateTime RMVideoFileList::simpleFromDateTime(QDateTime& startTime)
|
|
{
|
|
int hour = startTime.time().hour();
|
|
int perHour = 1;//3600 / 3600;
|
|
if(perHour != 1)
|
|
{
|
|
hour = hour - (hour % perHour);
|
|
}
|
|
return bSortDsc ? QDateTime(startTime.date(),QTime(hour,0,0)).addSecs(3600) : QDateTime(startTime.date(),QTime(hour,0,0));
|
|
}
|
|
QDateTime RMVideoFileList::simpleFromDateTime2(QDateTime& startTime)
|
|
{
|
|
int hour = startTime.time().hour();
|
|
int perHour = 1;//3600 / 3600;
|
|
if(perHour != 1)
|
|
{
|
|
hour = hour - (hour % perHour);
|
|
}
|
|
return (!bSortDsc) ? QDateTime(startTime.date(),QTime(hour,0,0)).addSecs(3600) : QDateTime(startTime.date(),QTime(hour,0,0));
|
|
}
|
|
void RMVideoFileList::load1HourList(QList<RMVideoItem*>& res)
|
|
{
|
|
res.clear();
|
|
// N 시간 단위로 파일 추가
|
|
QDateTime lastDateTime = QDateTime();
|
|
foreach (RMVideoItem* item, _items) {
|
|
|
|
item->checked = false;
|
|
QDateTime currentTime = item->startTime();
|
|
if(bSortDsc) {
|
|
if(lastDateTime.isValid() == true && -lastDateTime.secsTo(currentTime) < 3600 ) {
|
|
continue;
|
|
}
|
|
}
|
|
else {
|
|
if(lastDateTime.isValid() == true && lastDateTime.secsTo(currentTime) < 3600 ) {
|
|
continue;
|
|
}
|
|
}
|
|
res.append(item);
|
|
lastDateTime = simpleFromDateTime(item->startTime());
|
|
}
|
|
}
|
|
void RMVideoFileList::load1HourInList(QDateTime dt, QList<RMVideoItem*>& res)
|
|
{
|
|
res.clear();
|
|
QDateTime fromDateTime = simpleFromDateTime(dt);
|
|
foreach (RMVideoItem* item, _items)
|
|
{
|
|
qint64 diff = fromDateTime.secsTo(item->startTime());
|
|
if(bSortDsc) {
|
|
diff *= -1;
|
|
}
|
|
if(diff >= 0 && diff < 3600)
|
|
{
|
|
res.append(item);
|
|
}
|
|
}
|
|
}
|
|
QPair<QString,QString> RMVideoFileList::getThumbnailPath(RMVideoItem* item)
|
|
{
|
|
// C:\stroage\testing\TELEBIT\20231116_TB4000_SD3\Video\2023_11\15\17\20231115-172447_PSR0_0000.tb4
|
|
// C:\stroage\testing\TELEBIT\20231116_TB4000_SD3\Photo\2023_11\15\17\20231115-172447_PSR0_0000_0.jpg
|
|
// C:\stroage\testing\TELEBIT\20231116_TB4000_SD3\Photo\2023_11\15\17\20231115-172447_PSR0_0000_1.jpg
|
|
QString src = item->filePath;
|
|
if(QFile::exists(item->filePath)){
|
|
int idx = src.lastIndexOf("Video");
|
|
if(idx >= 0) {
|
|
QString base = src.replace(idx,5,"Photo");
|
|
QString f = base;
|
|
f.replace(".tb4","_0.jpg");
|
|
if(!QFile::exists(f)) {
|
|
f = "";
|
|
}
|
|
QString s = base;
|
|
s.replace(".tb4","_1.jpg");
|
|
if(!QFile::exists(s)) {
|
|
s = "";
|
|
}
|
|
return QPair<QString,QString>(f,s);
|
|
}
|
|
}
|
|
return QPair<QString,QString>("","");
|
|
}
|
|
void RMVideoFileList::loadThumbnails(QList<RMVideoItem*>& src, QList<QPair<QString,QString>>& res)
|
|
{
|
|
res.clear();
|
|
// Thumbnail 과 동기화를 위해 존재하지 않는 아이템은 제거
|
|
QList<RMVideoItem*> removes = QList<RMVideoItem*>();
|
|
foreach (RMVideoItem* item, src)
|
|
{
|
|
QPair<QString,QString> paths = getThumbnailPath(item);
|
|
if(paths.first.isEmpty() && paths.second.isEmpty()) {
|
|
// removes.append(item); // 제거하지 않고 NO_THUMBNAIL 추가
|
|
// continue;
|
|
// 문제는 NO IMAGE 로는 이미지 선택시 재생할 수 없음..
|
|
QString name = QFileInfo(item->filePath).baseName();
|
|
paths = QPair<QString,QString>(name+"_0",name+"_1");
|
|
// ":/image/no_thumbnail.png",":/image/no_thumbnail.png"
|
|
}
|
|
res.append(paths);
|
|
}
|
|
// Thumbnail 과 동기화를 위해 존재하지 않는 아이템은 제거
|
|
//foreach (RMVideoItem* item, removes)
|
|
//{
|
|
// src.removeOne(item);
|
|
//}
|
|
}
|
|
void RMVideoFileList::count1HourItems()
|
|
{
|
|
count1Hour = 0;
|
|
// N 시간 단위로 파일 추가
|
|
QDateTime lastDateTime = QDateTime();
|
|
foreach (RMVideoItem* item, _items) {
|
|
|
|
QDateTime currentTime = item->startTime();
|
|
if(bSortDsc) {
|
|
if(lastDateTime.isValid() == true && -lastDateTime.secsTo(currentTime) < 3600 ) {
|
|
continue;
|
|
}
|
|
}
|
|
else {
|
|
if(lastDateTime.isValid() == true && lastDateTime.secsTo(currentTime) < 3600 ) {
|
|
continue;
|
|
}
|
|
}
|
|
count1Hour++;
|
|
lastDateTime = simpleFromDateTime(item->startTime());
|
|
}
|
|
|
|
}
|
|
void RMVideoFileList::set1HourList(bool b1Hour, bool bEmit, RMVideoItem* selected)
|
|
{
|
|
if(bEmit) {
|
|
emit listUpdateStarted(false);
|
|
}
|
|
_filteredItems.clear();
|
|
b1HourList = b1Hour;
|
|
if(b1HourList) {
|
|
load1HourList(_filteredItems);
|
|
} else {
|
|
foreach (RMVideoItem* item, _items) {
|
|
item->checked = false;
|
|
_filteredItems.append(item);
|
|
}
|
|
}
|
|
|
|
// N 시간 단위로 파일 추가
|
|
// QDateTime lastDateTime = QDateTime();
|
|
// foreach (RMVideoItem* item, _items) {
|
|
|
|
// if(b1Hour) {
|
|
// QDateTime currentTime = item->startTime();
|
|
// if(bSortDsc) {
|
|
// if(lastDateTime.isValid() == true && -lastDateTime.secsTo(currentTime) < 3600 ) {
|
|
// continue;
|
|
// }
|
|
// }
|
|
// else {
|
|
// if(lastDateTime.isValid() == true && lastDateTime.secsTo(currentTime) < 3600 ) {
|
|
// continue;
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
// item->checked = false;
|
|
// _filteredItems.append(item);
|
|
// if(b1Hour) {
|
|
// lastDateTime = simpleFromDateTime(item->startTime());
|
|
// }
|
|
// }
|
|
setPlayItem(NULL);
|
|
|
|
|
|
if(bEmit) {
|
|
emit listUpdateEnd(false,findFirstItemIn1Hour(selected));
|
|
}
|
|
}
|
|
|
|
void RMVideoFileList::setSortList(bool bDsc)
|
|
{
|
|
bSortDsc = bDsc;
|
|
qSort(_items.begin(),_items.end(),RMVideoItemCompare);
|
|
}
|
|
#endif // #if (USE_1HOUR_FILTER)
|
|
/*
|
|
bool RMVideoFileList::_updateChannel(QString filePath,bool isCH2)
|
|
{
|
|
QString srcName = _checkChannelInfo(filePath,NULL);
|
|
foreach (RMVideoItem* item, _items)
|
|
{
|
|
QString destPath = isCH2 ? item->filePath : item->filePathCH2;
|
|
bool destIsCH2 = false;
|
|
QString destName = _checkChannelInfo(destPath,&destIsCH2);
|
|
if(srcName.compare(destName,Qt::CaseInsensitive) == 0 && isCH2 != destIsCH2)
|
|
{
|
|
if (isCH2 == true)
|
|
{
|
|
item->filePathCH2 = filePath;
|
|
}
|
|
else
|
|
{
|
|
item->filePath = filePath;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
*/
|
|
|
|
#if !(USE_1HOUR_FILTER)
|
|
void RMVideoFileList::setFilterSingle(RMVideoFileList::FILTER filter)
|
|
{
|
|
_filter = filter;
|
|
_updateItemsByFilter();
|
|
}
|
|
|
|
void RMVideoFileList::setFilter(RMVideoFileList::FILTER filter, bool on)
|
|
{
|
|
if(on){
|
|
_filter = _filter | filter;
|
|
}
|
|
else {
|
|
_filter = _filter & ~filter;
|
|
}
|
|
_updateItemsByFilter();
|
|
}
|
|
void RMVideoFileList::clearChecked()
|
|
{
|
|
foreach (RMVideoItem* item, _items) {
|
|
item->checked = false;
|
|
}
|
|
}
|
|
|
|
void RMVideoFileList::_updateItemsByFilter()
|
|
{
|
|
emit listUpdateStarted(false);
|
|
_filteredItems.clear();
|
|
foreach (RMVideoItem* item, _items) {
|
|
|
|
// 전방이 없을 경우 강제 전방 표시
|
|
// Player 의 Rearswap 사용
|
|
// if(item->isSingleChannel() && item->filePath.isEmpty()) {
|
|
// item->filePath = item->filePathCH2;
|
|
// item->filePathCH2 = "";
|
|
// item->forceSwap = true;
|
|
// } else {
|
|
// item->forceSwap = false;
|
|
// }
|
|
|
|
item->checked = false;
|
|
RMVideoFileList::FILTER filter = filterTypeFromGroupType(item->type);
|
|
|
|
if(checkFilter(filter)) {
|
|
_filteredItems.append(item);
|
|
}
|
|
}
|
|
setPlayItem(NULL);
|
|
emit listUpdateEnd(false,NULL);
|
|
}
|
|
#endif // #if !(USE_1HOUR_FILTER)
|
|
// 모델별로 채널 확인해서 처리해야 하는 기능
|
|
bool RMVideoFileList::itemExist(QString filePath)
|
|
{
|
|
#if (RM_MODEL_EMT_KR)
|
|
QString search = filePath;
|
|
#else // RM_MODEL_EMT_KR
|
|
#if (FORCE_2CH || SINGLE_CH_VIEWER)
|
|
QString search = QFileInfo(filePath).baseName();
|
|
#else // FORCE_2CH
|
|
QString search = RMVideoItem::fileNameWithoutChannel(filePath);
|
|
#endif // FORCE_2CH
|
|
#endif // !RM_MODEL_EMT_KR
|
|
|
|
foreach (RMVideoItem* item, _items)
|
|
{
|
|
#if (RM_MODEL_EMT_KR)
|
|
// MYBOX 가 존재하니 단순 경로만 비교
|
|
if(search.compare(item->filePath,Qt::CaseInsensitive) == 0) {
|
|
return true;
|
|
}
|
|
#else // RM_MODEL_EMT_KR
|
|
#if (FORCE_2CH || SINGLE_CH_VIEWER)
|
|
QString compare = QFileInfo(item->anyFilePath()).baseName();
|
|
#else
|
|
QString compare = RMVideoItem::fileNameWithoutChannel(item->anyFilePath());
|
|
#endif
|
|
if(search.compare(compare,Qt::CaseInsensitive) == 0) {
|
|
return true;
|
|
}
|
|
#endif // !RM_MODEL_EMT_KR
|
|
}
|
|
return false;//_updateChannel(filePath,isCH2);
|
|
}
|
|
// 멀티파일(채널) 포멧 확인하고 날짜제외 제거하고 리턴
|
|
|
|
#if (RM_MODEL == RM_MODEL_TYPE_NX_DRW22)
|
|
QString RMVideoFileList::_checkChannelInfo(QString filePath,bool *isCH2)
|
|
{
|
|
QString baseName = QFileInfo(filePath).baseName();
|
|
if(isCH2 != NULL)
|
|
{
|
|
*isCH2 = baseName.endsWith("R",Qt::CaseInsensitive);
|
|
}
|
|
// 동일한 영상/전후방 비교용으로만 사용됨
|
|
baseName.truncate(baseName.length()-1);
|
|
return baseName;
|
|
}
|
|
// 전방 또는 후방 파일 확인해서 추가
|
|
|
|
bool RMVideoFileList::_addOtherChannelFile(RMVideoItem *item) {
|
|
|
|
QString filePath = item->anyFilePath();
|
|
QString fileFolder = QFileInfo(filePath).absolutePath();
|
|
|
|
|
|
bool isCH2 = false;
|
|
QString searchFileName;
|
|
QString baseName = RMVideoFileList::_checkChannelInfo(filePath,&isCH2);
|
|
|
|
// 탐색할 파일명
|
|
searchFileName = baseName + (isCH2 ? "F.mov" : "R.mov");
|
|
QStringList searchPaths = QStringList() << QDir::cleanPath((fileFolder + QDir::separator() + searchFileName));
|
|
|
|
// 폴더의 폴더
|
|
QString fileFolderFolder = QFileInfo(fileFolder).baseName();
|
|
if(fileFolderFolder == "F" || fileFolderFolder == "R") {
|
|
QString searchFolder = (fileFolderFolder == "F" ? "R" : "F");
|
|
|
|
searchPaths << (QDir::cleanPath(QFileInfo(fileFolder).absolutePath() + QDir::separator() + searchFolder + QDir::separator() + searchFileName));
|
|
}
|
|
|
|
// 탐색폴더 확인
|
|
foreach (QString path, searchPaths) {
|
|
|
|
if( QFile::exists(path) ) {
|
|
if(isCH2) {
|
|
item->filePath = path;
|
|
}
|
|
else {
|
|
item->filePathCH2 = path;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
QString RMVideoFileList::groupTypeFromFilePath(QString filePath,RMVideoFileList::GROUP_TYPE* type)
|
|
{
|
|
QString cleanPath = filePath.toUpper();
|
|
QString baseName = QFileInfo(cleanPath).baseName();
|
|
|
|
// FILE200713-101324-000001F.MOV
|
|
// EMER200713-101525-000003F.MOV
|
|
|
|
QRegExp regexp("^[F,E][I,M][L,E][E,R][0-9]{6}-[0-9]{6}-[0-9]{6}[F,R]");
|
|
if(!regexp.exactMatch(baseName)) {
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
|
|
if(baseName.startsWith("F")) {
|
|
*type = TYPE_NORMAL;
|
|
}
|
|
else {
|
|
*type = TYPE_EVENT;
|
|
}
|
|
return baseName.mid(4,13);
|
|
}
|
|
#elif (RM_MODEL == RM_MODEL_TYPE_MH9000)
|
|
QString RMVideoFileList::groupTypeFromFilePath(QString filePath,RMVideoFileList::GROUP_TYPE* type)
|
|
{
|
|
QString baseName = QFileInfo(QDir::cleanPath(filePath)).baseName();
|
|
QRegExp regexp("^(:?NORM|EVEN|PARK|MANU)[0-9]{6}-[0-9]{6}(:?FR|LS|RR|RS|IN)"); // EX->IN 으로 변경
|
|
regexp.setCaseSensitivity(Qt::CaseInsensitive);
|
|
// 240523-174742
|
|
if(regexp.exactMatch(baseName)) {
|
|
if(baseName.startsWith("EVEN")) {
|
|
*type = TYPE_EVENT;
|
|
}
|
|
else if(baseName.startsWith("PARK")) {
|
|
*type = TYPE_PARKING;
|
|
}
|
|
else if(baseName.startsWith("MANU")) {
|
|
*type = TYPE_MANUAL;
|
|
}else {
|
|
*type = TYPE_NORMAL;
|
|
}
|
|
}
|
|
return baseName;
|
|
}
|
|
QString RMVideoFileList::_checkChannelInfo(QString filePath,int *ch)
|
|
{
|
|
QString baseName = QFileInfo(filePath).baseName();
|
|
QRegExp regexp("^(:?NORM|EVEN|PARK|MANU)[0-9]{6}-[0-9]{6}(:?FR|LS|RR|RS|IN)"); // EX->IN 으로 변경
|
|
if(regexp.exactMatch(baseName)) {
|
|
if(baseName.endsWith("FR")) {
|
|
*ch = (int)RMApp::ChannelFront;
|
|
}
|
|
else if(baseName.endsWith("RR")) {
|
|
*ch = (int)RMApp::ChannelRear;
|
|
}
|
|
else if(baseName.endsWith("LS")) {
|
|
*ch = (int)RMApp::ChannelLeft;
|
|
}
|
|
else if(baseName.endsWith("RS")) {
|
|
*ch = (int)RMApp::ChannelRight;
|
|
}
|
|
else if(baseName.endsWith("IN")) {
|
|
*ch = (int)RMApp::ChannelSub;
|
|
}
|
|
}
|
|
// 동일한 영상/전후방 비교용으로만 사용됨
|
|
baseName.truncate(baseName.length()-2);
|
|
return baseName;
|
|
}
|
|
bool RMVideoFileList::_addOtherChannelFile(RMVideoItem *item) {
|
|
|
|
QString filePath = item->anyFilePath();
|
|
QString fileFolder = QFileInfo(filePath).absolutePath();
|
|
// 탐색폴더 확인
|
|
bool found = false;
|
|
|
|
int ch = -1;
|
|
QString baseName = RMVideoFileList::_checkChannelInfo(filePath,&ch);
|
|
if(ch >= 0 && ch <= 4) {
|
|
//QStringList searchFileNames = QStringList();
|
|
QStringList searchFileNames = QStringList() << "FR.mp4" << "RR.mp4" << "LS.mp4" << "RS.mp4" << "IN.mp4"; // EX->IN
|
|
// RR 이 먼저 확인되어도 모두 처리가능하도록 변경
|
|
// searchFileNames.removeAt(ch);
|
|
foreach (QString path, searchFileNames) {
|
|
|
|
//qInfo() << baseName << path << __FUNCTION__;
|
|
QString fullPath = QDir::cleanPath((fileFolder + QDir::separator() + baseName + path));
|
|
if( QFile::exists(fullPath) ) {
|
|
int fc = 0;
|
|
RMVideoFileList::_checkChannelInfo(fullPath,&fc);
|
|
if(fc == 0) {
|
|
item->filePath = fullPath;
|
|
}
|
|
else if (fc == 1) {
|
|
item->filePathCH2 = fullPath;
|
|
}
|
|
else if (fc == 2) {
|
|
item->filePathCH3 = fullPath;
|
|
}
|
|
else if (fc == 3) {
|
|
item->filePathCH4 = fullPath;
|
|
}
|
|
else if (fc == 4) {
|
|
item->filePathCH5 = fullPath;
|
|
}
|
|
found = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return found;
|
|
}
|
|
#elif (RM_MODEL_EMT_KR)
|
|
RMVideoFileList::GROUP_TYPE RMVideoFileList::parseName(QString baseName, QDateTime* dateTime, int* tag)
|
|
{
|
|
if(tag != NULL) {
|
|
*tag = 0;
|
|
}
|
|
if(dateTime != NULL) {
|
|
dateTime->swap(QDateTime()); // INVALID
|
|
}
|
|
|
|
// 상시폴더
|
|
// 250610_18h14m35s_Driving_sde.MP4 (일본향 sdexit, 파일 생성시)
|
|
// 250610_18h02m35s_Driving.MP4 (정상 종료)
|
|
// 250610_18h00m30s_Driving_res.MP4 (복구 파일)
|
|
// 상시 이벤트
|
|
// 250610_18h18m29s_EventShock.MP4 (상시 이벤트)
|
|
// 매뉴얼 이벤트
|
|
// 250610_18h17m36s_Manual.MP4 (매뉴얼 이벤트 )
|
|
// 주차폴더
|
|
// 250610_18h18m09s_Parking.MP4
|
|
// 250610_18h18m09s_Parkin_htp.MP4 (고온종료)
|
|
// 250610_18h18m09s_Parkin_lbp.MP4 (차단전압)"
|
|
// ParkingShock 이 Parking 보다 먼저 사용되어야 함
|
|
static QRegularExpression rx("^(?P<ymd>\\d{6})_(?P<hour>\\d{2})h(?P<minutes>\\d{2})m(?P<second>\\d{2})s_(?P<type>Driving|EventShock|EventAI|Manual|ParkingShock|Parking)(?:_(?P<tag>res|htp|lbp|RC|CD))?",QRegularExpression::CaseInsensitiveOption);
|
|
QRegularExpressionMatch match = rx.match(baseName);
|
|
if (!match.isValid()) {
|
|
return TYPE_UNDEFINED;
|
|
}
|
|
|
|
// 날짜 처리
|
|
if(dateTime != NULL) {
|
|
QString dateString = "20" + match.captured("ymd") + "_" + match.captured("hour") + match.captured("minutes") + match.captured("second");
|
|
dateTime->swap(QDateTime::fromString(dateString,"yyyyMMdd_HHmmss"));
|
|
}
|
|
// 태그 처리
|
|
if(tag != NULL && !match.captured("tag").isEmpty()) {
|
|
QString tagString = match.captured("tag").toLower();
|
|
// res = 1|htp = 2|lbp = 3
|
|
if(tagString == "res") {
|
|
*tag = 1;
|
|
}
|
|
else if(tagString == "htp") {
|
|
*tag = 2;
|
|
}
|
|
else if(tagString == "lbp") {
|
|
*tag = 3;
|
|
}
|
|
else if(tagString == "rc") { //후방추돌
|
|
*tag = 4;
|
|
}
|
|
else if(tagString == "cd") { // 끼어들기
|
|
*tag = 5;
|
|
}
|
|
}
|
|
QString typeString = match.captured("type").toLower();
|
|
//qInfo() << baseName << typeString << match.captured("tag") << __FUNCTION__;
|
|
if(typeString == "driving") {
|
|
return TYPE_NORMAL;
|
|
} else if (typeString == "eventshock" || typeString == "eventai") {
|
|
return TYPE_EVENT;
|
|
} else if (typeString == "manual") {
|
|
return TYPE_MANUAL;
|
|
} else if (typeString == "parking") {
|
|
return TYPE_PARKING;
|
|
} else if (typeString == "parkingshock") {
|
|
return TYPE_PARKING_EVENT;
|
|
}
|
|
return TYPE_UNDEFINED;
|
|
}
|
|
QString RMVideoFileList::groupTypeFromFilePath(QString filePath,RMVideoFileList::GROUP_TYPE* type)
|
|
{
|
|
|
|
// 20250528_13h42m07s_Driving
|
|
QString baseName = QFileInfo(QDir::cleanPath(filePath)).baseName();
|
|
*type = parseName(baseName,NULL,NULL);
|
|
|
|
QString folderName = QFileInfo(filePath).dir().dirName().toUpper();
|
|
if(folderName == "MYBOX") {
|
|
*type = RMVideoFileList::TYPE_MY_BOX;
|
|
}
|
|
return baseName;
|
|
}
|
|
#elif (RM_MODEL == RM_MODEL_TYPE_TB4000)
|
|
QString RMVideoFileList::groupTypeFromFilePath(QString filePath,RMVideoFileList::GROUP_TYPE* type)
|
|
{
|
|
QString baseName = QFileInfo(QDir::cleanPath(filePath)).baseName();
|
|
// 20230815-070258_REC_0000.mp4
|
|
*type = TYPE_NORMAL;
|
|
return baseName;
|
|
}
|
|
#elif (RM_MODEL == RM_MODEL_TYPE_KEIYO1 || RM_MODEL == RM_MODEL_TYPE_MBJ5010 || RM_MODEL == RM_MODEL_TYPE_FC_DR232W || RM_MODEL == RM_MODEL_TYPE_BV2000)
|
|
#if !(FORCE_2CH)
|
|
#if (TRI_CHANNEL)
|
|
QString RMVideoFileList::_checkChannelInfo(QString filePath,int *ch)
|
|
#else
|
|
QString RMVideoFileList::_checkChannelInfo(QString filePath,bool *isCH2, bool *is2CH)
|
|
#endif
|
|
{
|
|
QString baseName = QFileInfo(filePath).baseName();
|
|
#if (TRI_CHANNEL)
|
|
if(ch != NULL)
|
|
{
|
|
if(baseName.endsWith("R",Qt::CaseInsensitive)) {
|
|
*ch = 2;
|
|
}
|
|
else if(baseName.endsWith("I",Qt::CaseInsensitive)) {
|
|
*ch = 3;
|
|
}
|
|
else {
|
|
*ch = 1;
|
|
}
|
|
}
|
|
#else // TRI_CHANNEL
|
|
if(isCH2 != NULL)
|
|
{
|
|
if(baseName.endsWith("R",Qt::CaseInsensitive)) {
|
|
*isCH2 = true;
|
|
}
|
|
else {
|
|
*isCH2 = false;
|
|
}
|
|
}
|
|
#endif // #if (TRI_CHANNEL)
|
|
|
|
#if (SUPPORT_2CH)
|
|
if(is2CH != NULL)
|
|
{
|
|
*is2CH = baseName.endsWith("W",Qt::CaseInsensitive);
|
|
}
|
|
#endif // SUPPORT_2CH
|
|
// 동일한 영상/전후방 비교용으로만 사용됨
|
|
baseName.truncate(baseName.length()-1);
|
|
return baseName;
|
|
}
|
|
// 전방 또는 후방 파일 확인해서 추가
|
|
|
|
bool RMVideoFileList::_addOtherChannelFile(RMVideoItem *item) {
|
|
|
|
QString filePath = item->anyFilePath();
|
|
QString fileFolder = QFileInfo(filePath).absolutePath();
|
|
|
|
#if (TRI_CHANNEL)
|
|
int ch;
|
|
QString baseName = RMVideoFileList::_checkChannelInfo(filePath,&ch);
|
|
QStringList searchFileNames = QStringList();
|
|
if (ch == 1) {
|
|
searchFileNames << "R.mp4" << "I.mp4";
|
|
}
|
|
else if (ch == 2) {
|
|
searchFileNames << "F.mp4" << "I.mp4";
|
|
}
|
|
else if (ch == 3) {
|
|
searchFileNames << "F.mp4" << "R.mp4";
|
|
}
|
|
|
|
//QStringList searchPaths = QStringList() << QDir::cleanPath((fileFolder + QDir::separator() + searchFileName));
|
|
// 탐색폴더 확인
|
|
bool found = false;
|
|
foreach (QString path, searchFileNames) {
|
|
|
|
QString fullPath = QDir::cleanPath((fileFolder + QDir::separator() + baseName + path));
|
|
if( QFile::exists(fullPath) ) {
|
|
int fc = 0;
|
|
RMVideoFileList::_checkChannelInfo(fullPath,&fc);
|
|
if(fc == 1) {
|
|
item->filePath = fullPath;
|
|
}
|
|
else if (fc == 2) {
|
|
item->filePathCH2 = fullPath;
|
|
}
|
|
else if (fc == 3) {
|
|
item->filePathCH3 = fullPath;
|
|
}
|
|
found = true;
|
|
}
|
|
}
|
|
return found;
|
|
#else
|
|
QString searchFileName;
|
|
bool isCH2 = false;
|
|
QString baseName = RMVideoFileList::_checkChannelInfo(filePath,&isCH2);
|
|
// 탐색할 파일명
|
|
searchFileName = baseName + (isCH2 ? "F.mp4" : "R.mp4");
|
|
QStringList searchPaths = QStringList() << QDir::cleanPath((fileFolder + QDir::separator() + searchFileName));
|
|
|
|
// 폴더의 폴더
|
|
// QString fileFolderFolder = QFileInfo(fileFolder).baseName();
|
|
// if(fileFolderFolder == "F" || fileFolderFolder == "R") {
|
|
// QString searchFolder = (fileFolderFolder == "F" ? "R" : "F");
|
|
|
|
// searchPaths << (QDir::cleanPath(QFileInfo(fileFolder).absolutePath() + QDir::separator() + searchFolder + QDir::separator() + searchFileName));
|
|
// }
|
|
|
|
// 탐색폴더 확인
|
|
foreach (QString path, searchPaths) {
|
|
|
|
if( QFile::exists(path) ) {
|
|
if(isCH2) {
|
|
item->filePath = path;
|
|
}
|
|
else {
|
|
item->filePathCH2 = path;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
#endif
|
|
|
|
|
|
}
|
|
#endif // #if !(FORCE_2CH)
|
|
QString RMVideoFileList::groupTypeFromFilePath(QString filePath,RMVideoFileList::GROUP_TYPE* type)
|
|
{
|
|
QString cleanPath = filePath.toUpper();
|
|
QString baseName = QFileInfo(cleanPath).baseName();
|
|
|
|
#if (SUB_MODEL_KEIYO_360)
|
|
// NORM230517-104840I.MP4
|
|
QRegExp regexp("^(NORM|EVEN)[0-9]{6}-[0-9]{6}[I,W]");
|
|
if(!regexp.exactMatch(baseName)) {
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
if(baseName.startsWith("NORM")) {
|
|
*type = TYPE_NORMAL;
|
|
}
|
|
else if (baseName.startsWith("EVEN")) {
|
|
*type = TYPE_EVENT;
|
|
}
|
|
return baseName.mid(4,6+1+6);
|
|
#else // #if (SUB_MODEL_KEIYO_360)
|
|
// NORM201029-085403F
|
|
// EVEN201029-085721F
|
|
// MANU201029-090032F
|
|
// PARK201029-091752F
|
|
|
|
// PEVE190116-173653F.MP4 // 주차 이벤트
|
|
// PNOR190120-211045F.MP4 // 주차 상시
|
|
#if (SUPPORT_2CH || FORCE_2CH)
|
|
QRegExp regexp("^[N,E,M,P][O,V,A,E,N][R,E,N,V,O][M,N,U,K,E,R][0-9]{6}-[0-9]{6}[F,R,W]");
|
|
#else
|
|
QRegExp regexp("^[N,E,M,P][O,V,A,E,N][R,E,N,V,O][M,N,U,K,E,R][0-9]{6}-[0-9]{6}[F,R]");
|
|
#endif
|
|
if(!regexp.exactMatch(baseName)) {
|
|
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
|
|
if(baseName.startsWith("NORM")) {
|
|
*type = TYPE_NORMAL;
|
|
}
|
|
else if (baseName.startsWith("EVEN")) {
|
|
*type = TYPE_EVENT;
|
|
}
|
|
else if (baseName.startsWith("MANU")) {
|
|
*type = TYPE_MANUAL;
|
|
}
|
|
else if (baseName.startsWith("PARK")) {
|
|
*type = TYPE_PARKING;
|
|
}
|
|
else if (baseName.startsWith("PNOR")) { // 벤츠2
|
|
*type = TYPE_PARKING;
|
|
}
|
|
else if (baseName.startsWith("PEVE")) { // 벤츠2
|
|
*type = TYPE_PARKING_EVENT;
|
|
}
|
|
else {
|
|
*type = TYPE_NORMAL;
|
|
}
|
|
return baseName.mid(4,13);
|
|
#endif // #else // #if (SUB_MODEL_KEIYO_360)
|
|
}
|
|
#elif (RM_MODEL == RM_MODEL_TYPE_ADT_CAPS && !SUB_MODEL_CARROT_EMT)
|
|
QString RMVideoFileList::_checkChannelInfo(QString filePath,bool *isCH2, bool *is2CH)
|
|
{
|
|
QString baseName = QFileInfo(filePath).baseName();
|
|
if(isCH2 != NULL)
|
|
{
|
|
*isCH2 = baseName.contains("_R_",Qt::CaseInsensitive);
|
|
}
|
|
// 동일한 영상/전후방 비교용으로만 사용됨
|
|
baseName = baseName.replace("_R_","_#CH#_").replace("_F_","_#CH#_");
|
|
return baseName;
|
|
}
|
|
bool RMVideoFileList::_addOtherChannelFile(RMVideoItem *item) {
|
|
|
|
QString filePath = item->anyFilePath();
|
|
QString fileFolder = QFileInfo(filePath).absolutePath();
|
|
|
|
|
|
bool isCH2 = false;
|
|
QString searchFileName;
|
|
QString baseName = RMVideoFileList::_checkChannelInfo(filePath,&isCH2);
|
|
|
|
// 탐색할 파일명
|
|
searchFileName = baseName.replace("_#CH#_",isCH2 ? "_F_" : "_R_") + "." + FILE_EXT;
|
|
QStringList searchPaths = QStringList() << QDir::cleanPath((fileFolder + QDir::separator() + searchFileName));
|
|
|
|
// 폴더의 폴더
|
|
QString fileFolderFolder = QFileInfo(fileFolder).baseName();
|
|
if(fileFolderFolder == "1" || fileFolderFolder == "2") {
|
|
QString searchFolder = (fileFolderFolder == "1" ? "2" : "1");
|
|
|
|
searchPaths << (QDir::cleanPath(QFileInfo(fileFolder).absolutePath() + QDir::separator() + searchFolder + QDir::separator() + searchFileName));
|
|
}
|
|
|
|
// 탐색폴더 확인
|
|
foreach (QString path, searchPaths) {
|
|
|
|
if( QFile::exists(path) ) {
|
|
if(isCH2) {
|
|
item->filePath = path;
|
|
}
|
|
else {
|
|
item->filePathCH2 = path;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
QString RMVideoFileList::groupTypeFromFilePath(QString filePath,RMVideoFileList::GROUP_TYPE* type)
|
|
{
|
|
QString cleanPath = filePath.toUpper();
|
|
QString baseName = QFileInfo(cleanPath).baseName();
|
|
|
|
// 2020-06-12-17h-10m-05s_F_normal.mp4
|
|
QRegExp regexp("^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{2}H-[0-9]{2}M-[0-9]{2}S_[F,R]_[A-Z]*");
|
|
if(!regexp.exactMatch(baseName)) {
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
|
|
if(baseName.endsWith("_NORMAL",Qt::CaseInsensitive)) {
|
|
*type = TYPE_NORMAL;
|
|
}
|
|
else {
|
|
*type = TYPE_EVENT;
|
|
}
|
|
baseName.truncate(22);
|
|
// 2020-06-12-17H-10M-05S
|
|
return baseName;
|
|
}
|
|
#elif (RM_MODEL == RM_MODEL_TYPE_XLDR_88 || SUB_MODEL_CARROT_EMT)
|
|
QString RMVideoFileList::groupTypeFromFilePath(QString filePath,RMVideoFileList::GROUP_TYPE* type)
|
|
{
|
|
QString cleanPath = filePath.toUpper();
|
|
QString baseName = QFileInfo(cleanPath).baseName();
|
|
|
|
// S200727_110830FE_Exit
|
|
// S200526_110830FP
|
|
// S200727_100830FE_Exit
|
|
// S200827_100830FN_Exit
|
|
|
|
// 2021/07/21 추가
|
|
// S210217_001749FN_TEMP
|
|
// + _TEMP,_RCVR,_MENU,_LBAT
|
|
// S210217_001548FPE : 주차 충격
|
|
|
|
QRegExp regexp("^[S][0-9]{6}_[0-9]{6}[F][P,E,N,PE][_EXIT,_TEMP,_RCVR,_MENU,_LBAT,_PKTM]*"); //
|
|
if(!regexp.exactMatch(baseName)) {
|
|
qInfo() << "FILE ERROR:" << baseName << __FUNCTION__ << __LINE__;
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
|
|
QString typeString = baseName.mid(14,2).toUpper();
|
|
|
|
if(typeString == "FN") {
|
|
*type = TYPE_NORMAL;
|
|
}
|
|
else if(typeString == "FP") {
|
|
|
|
if (baseName.length() > 16 && baseName.mid(16,1).toUpper() == "E") { // FPE (PARKING EVENT)
|
|
*type = TYPE_PARKING; // 주차 충격은 주차로 이동
|
|
}
|
|
else {
|
|
*type = TYPE_PARKING;
|
|
}
|
|
}
|
|
else {
|
|
*type = TYPE_EVENT;
|
|
}
|
|
// qInfo() << filePath << "TYPE:" << *type;
|
|
return baseName.mid(1,13);
|
|
}
|
|
#elif (RM_MODEL == RM_MODEL_TYPE_AN6000)
|
|
int RMVideoFileList::parseSerial(QString baseName)
|
|
{
|
|
// 2023-12-31-07h-14m-07s_normal_1(1) 모두 처리
|
|
static QRegularExpression rx("^(?P<datetime>\\d{4}-\\d{2}-\\d{2}-\\d{2}h-\\d{2}m-\\d{2}s)_normal(_(?P<index>\\d{1,2}))?(\\((?P<index2>\\d{1,2})\\))?",QRegularExpression::CaseInsensitiveOption);
|
|
|
|
QRegularExpressionMatch match = rx.match(baseName);
|
|
if (!match.isValid()) {
|
|
return -1;
|
|
}
|
|
|
|
// 날짜 처리 -> 필요없음
|
|
//if(0) {
|
|
//dateTime->swap(QDateTime::fromString(match.captured("datetime"),"yyyy-MM-dd-HH'h'-mm'm'-ss's'"));
|
|
//}
|
|
int serial = 0;
|
|
if(!match.captured("index").isEmpty()) { // _1
|
|
serial = match.captured("index").toInt();
|
|
}
|
|
if(!match.captured("index2").isEmpty()) { // _1(2)
|
|
serial += match.captured("index2").toInt() + 100;
|
|
}
|
|
return serial;
|
|
}
|
|
QString RMVideoFileList::groupTypeFromFilePath(QString filePath,RMVideoFileList::GROUP_TYPE* type, int* serial)
|
|
{
|
|
QString cleanPath = filePath.toUpper();
|
|
QString baseName = QFileInfo(cleanPath).baseName();
|
|
*serial = parseSerial(baseName);
|
|
if(*serial < 0) {
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
if(baseName.contains("_NORMAL",Qt::CaseInsensitive)) {
|
|
*type = TYPE_NORMAL;
|
|
} else {
|
|
*type = TYPE_EVENT;
|
|
}
|
|
baseName.truncate(22);
|
|
return baseName;
|
|
|
|
/*
|
|
// 2020-06-12-17h-10m-05s_F_normal.mp4
|
|
// 2020-06-12-17h-10m-05s_F_normal(1).mp4 2024/09/24 추가
|
|
// 2020-06-12-17h-10m-05s_F_normal_1.mp4 2026/09/06 추가
|
|
// 2020-06-12-17h-10m-05s_F_normal_1(1).mp4 2026/09/06 추가
|
|
|
|
// QRegExp 는 '(' 문자는 [\(] 로만 처리됨
|
|
QRegExp regexp("^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{2}H-[0-9]{2}M-[0-9]{2}S_NORMAL([\(]{1}[1-9]{1}[\)]{1})?");
|
|
regexp.setCaseSensitivity(Qt::CaseInsensitive);
|
|
if(!regexp.exactMatch(baseName)) {
|
|
//qInfo() << "NO GROUP MATCH:" << baseName << __FUNCTION__;
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
//qInfo() << baseName << __FUNCTION__;
|
|
// (1)~(9) 처리
|
|
if(baseName.endsWith(")")) {
|
|
QStringList lst = baseName.split("(");
|
|
QString number = lst.last().replace(")","");
|
|
if(serial != NULL) {
|
|
*serial = number.toInt();
|
|
}
|
|
baseName = lst.first();
|
|
//qInfo() << "BASENAME:" << baseName << number << __FUNCTION__;
|
|
}
|
|
|
|
if(baseName.endsWith("_NORMAL",Qt::CaseInsensitive)) {
|
|
*type = TYPE_NORMAL;
|
|
}
|
|
else {
|
|
*type = TYPE_EVENT;
|
|
}
|
|
baseName.truncate(22);
|
|
// 2020-06-12-17H-10M-05S
|
|
return baseName;
|
|
*/
|
|
} // RM_MODEL_TYPE_AN6000
|
|
#elif (RM_MODEL == RM_MODEL_TYPE_XLDR_88 || SUB_MODEL_CARROT_EMT)
|
|
QString RMVideoFileList::groupTypeFromFilePath(QString filePath,RMVideoFileList::GROUP_TYPE* type)
|
|
{
|
|
QString cleanPath = filePath.toUpper();
|
|
QString baseName = QFileInfo(cleanPath).baseName();
|
|
|
|
// S200727_110830FE_Exit
|
|
// S200526_110830FP
|
|
// S200727_100830FE_Exit
|
|
// S200827_100830FN_Exit
|
|
|
|
// 2021/07/21 추가
|
|
// S210217_001749FN_TEMP
|
|
// + _TEMP,_RCVR,_MENU,_LBAT
|
|
// S210217_001548FPE : 주차 충격
|
|
|
|
QRegExp regexp("^[S][0-9]{6}_[0-9]{6}[F][P,E,N,PE][_EXIT,_TEMP,_RCVR,_MENU,_LBAT,_PKTM]*"); //
|
|
if(!regexp.exactMatch(baseName)) {
|
|
qInfo() << "FILE ERROR:" << baseName << __FUNCTION__ << __LINE__;
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
|
|
QString typeString = baseName.mid(14,2).toUpper();
|
|
|
|
if(typeString == "FN") {
|
|
*type = TYPE_NORMAL;
|
|
}
|
|
else if(typeString == "FP") {
|
|
|
|
if (baseName.length() > 16 && baseName.mid(16,1).toUpper() == "E") { // FPE (PARKING EVENT)
|
|
*type = TYPE_PARKING; // 주차 충격은 주차로 이동
|
|
}
|
|
else {
|
|
*type = TYPE_PARKING;
|
|
}
|
|
}
|
|
else {
|
|
*type = TYPE_EVENT;
|
|
}
|
|
// qInfo() << filePath << "TYPE:" << *type;
|
|
return baseName.mid(1,13);
|
|
}
|
|
|
|
|
|
#elif (RM_MODEL == RM_MODEL_TYPE_TBD360)
|
|
#if (!FORCE_2CH || (RM_MODEL == RM_MODEL_TYPE_XLDR_88 || SUB_MODEL_CARROT_EMT))
|
|
QString RMVideoFileList::_checkChannelInfo(QString filePath,bool *isCH2, bool *is2CH)
|
|
{
|
|
QString baseName = QFileInfo(filePath).baseName();
|
|
if(isCH2 != NULL)
|
|
{
|
|
*isCH2 = baseName.contains("_R_",Qt::CaseInsensitive);
|
|
}
|
|
// 동일한 영상/전후방 비교용으로만 사용됨
|
|
baseName = baseName.replace("_R_","_#CH#_").replace("_F_","_#CH#_");
|
|
return baseName;
|
|
}
|
|
bool RMVideoFileList::_addOtherChannelFile(RMVideoItem *item) {
|
|
|
|
QString filePath = item->anyFilePath();
|
|
QString fileFolder = QFileInfo(filePath).absolutePath();
|
|
|
|
|
|
bool isCH2 = false;
|
|
QString searchFileName;
|
|
QString baseName = RMVideoFileList::_checkChannelInfo(filePath,&isCH2);
|
|
|
|
// 탐색할 파일명
|
|
searchFileName = baseName.replace("_#CH#_",isCH2 ? "_F_" : "_R_") + "." + FILE_EXT;
|
|
QStringList searchPaths = QStringList() << QDir::cleanPath((fileFolder + QDir::separator() + searchFileName));
|
|
|
|
// 폴더의 폴더
|
|
QString fileFolderFolder = QFileInfo(fileFolder).baseName();
|
|
if(fileFolderFolder == "Front" || fileFolderFolder == "Rear") {
|
|
QString searchFolder = (fileFolderFolder == "Front" ? "Rear" : "Front");
|
|
|
|
searchPaths << (QDir::cleanPath(QFileInfo(fileFolder).absolutePath() + QDir::separator() + searchFolder + QDir::separator() + searchFileName));
|
|
}
|
|
|
|
// 탐색폴더 확인
|
|
foreach (QString path, searchPaths) {
|
|
|
|
if( QFile::exists(path) ) {
|
|
if(isCH2) {
|
|
item->filePath = path;
|
|
}
|
|
else {
|
|
item->filePathCH2 = path;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
#endif // #if (!FORCE_2CH || (RM_MODEL == RM_MODEL_TYPE_XLDR_88 || SUB_MODEL_CARROT_EMT))
|
|
|
|
QString RMVideoFileList::groupTypeFromFilePath(QString filePath,RMVideoFileList::GROUP_TYPE* type)
|
|
{
|
|
QString cleanPath = filePath.toUpper();
|
|
QString baseName = QFileInfo(cleanPath).baseName();
|
|
#if (TANDF_360_TEST)
|
|
// NNF_210212-101925-000055_1.MP4
|
|
QRegExp regexp("^[A-Z]{3}_[0-9]{6}-[0-9]{6}-[0-9]{6}_[1,2]{1}");
|
|
if(!regexp.exactMatch(baseName)) {
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
*type = TYPE_NORMAL;
|
|
// NNF_210212-101925-000055_1
|
|
return baseName.mid(4,6+1+6);
|
|
#elif (THINKWARE_DEMO)
|
|
// 20231102_141152E .MP4
|
|
QRegExp regexp("^[0-9]{8}_[0-9]{6}[E,M,N]{1}");
|
|
if(!regexp.exactMatch(baseName)) {
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
*type = TYPE_NORMAL;
|
|
// NNF_210212-101925-000055_1
|
|
return baseName.mid(0,15);
|
|
#elif (TEST_FILENAME)
|
|
QRegExp regexp("^TEST_[0-9]{8}-[0-9]{6}");
|
|
if(!regexp.exactMatch(baseName)) {
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
*type = TYPE_NORMAL;
|
|
return baseName.mid(5,8+1+6);
|
|
#elif (MH_360_TEST)
|
|
// NORM230517-104840I.MP4
|
|
QRegExp regexp("^NORM[0-9]{6}-[0-9]{6}I");
|
|
if(!regexp.exactMatch(baseName)) {
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
*type = TYPE_NORMAL;
|
|
return baseName.mid(4,6+1+6);
|
|
#else // TANDF_360_TEST
|
|
|
|
// 20201208_215045_F_Nor.AVI
|
|
// 20201208_151241_F_Gsn.AVI
|
|
QRegExp regexp("^[0-9]{8}_[0-9]{6}_[F,R]_[A-z]*");
|
|
if(!regexp.exactMatch(baseName)) {
|
|
*type = TYPE_UNDEFINED;
|
|
return "";
|
|
}
|
|
|
|
if(baseName.endsWith("_Nor",Qt::CaseInsensitive)) {
|
|
*type = TYPE_NORMAL;
|
|
}
|
|
else if(baseName.endsWith("_Gsn",Qt::CaseInsensitive)) {
|
|
*type = TYPE_EVENT;
|
|
}
|
|
else {
|
|
*type = TYPE_NORMAL;
|
|
}
|
|
baseName.truncate(15);
|
|
// 20201208_151241
|
|
#endif // TANDF_360_TEST
|
|
return baseName;
|
|
}
|
|
#endif // MODEL
|
|
|
|
|