#include "emovie.h" #include "emovieattr.h" #include #include #include //#include "qffwidget.h" extern "C"{ #include #include #include #include } eMovie::eMovie(QRectF rectInit,const QString &file,QWidget *pp,InteractiveType type, QGraphicsItem *parent) : eObject(rectInit,type, parent) { m_iType=eObject::Movie; qDebug()<<"eMovie::eMovie"; QFileInfo fi(file); m_attr.strRawName = fi.fileName(); m_attr.strRawPath = fi.absolutePath(); // qDebug()<<"ConvertVideoFormat"; if(!file.isNull()) { QString strConvertFile=ConvertVideoFormatByFFmpeg(file); QFileInfo outfi(strConvertFile); m_attr.name = outfi.fileName(); m_attr.path = outfi.absolutePath(); } setPlayArg(Qt::IgnoreAspectRatio, 10, 1); qDebug()<<"GetVideoTimeRawSpan"; m_attr.playDuration=GetVideoTimeRawSpan(file); qreal w = rectInit.width(); qreal h = w*m_display_aspect_ratio; if(w>rectInit.width()) w=rectInit.width(); if(h>rectInit.height()) h=rectInit.height(); setGeometry(QRectF(0, 0, w, h)); m_parentWidget=pp; init(true); qDebug()<<"eMovie::eMovie end"; //InitFfmpegSdl(); } eMovie::eMovie(const QJsonObject &json, const QString &pRoot, InteractiveType type, QGraphicsItem *parent) : eObject(json["geometry"].toObject(), type, parent) { m_iType=eObject::Movie; QJsonDocument jRoot(json); m_attr.name = jRoot["widget"]["file"].toString(); m_attr.path = jRoot["widget"]["path"].toString(); QString file0 = pRoot + MACRO_FENGEFU + m_attr.name ; QString file1 = m_attr.path + MACRO_FENGEFU + m_attr.name ; QFile f0(file0); QFile f1(file1); QString file; if(f0.exists()) { file = file0; } else if(f1.exists()) { file = file1; } else { setGeometry(RECTF_INVALID); return; } QFileInfo fi(file); setPlayArg(jRoot["play"]["aspectRatioMode"].toInt(), jRoot["play"]["playDuration"].toInt(), jRoot["play"]["playTimes"].toInt()); if(m_attr.playDuration<10); m_attr.playDuration=GetVideoTimeRawSpan(file); m_attr.strRawName=jRoot["widget"]["fileRaw"].toString(); m_attr.strRawPath=jRoot["widget"]["pathRaw"].toString(); init(false); //InitFfmpegSdl(); } eMovie::~eMovie() { if(m_vPlayer!=nullptr) { m_vPlayer->stop(); delete m_vPlayer ; } if(m_vPlayList!=nullptr) { delete m_vPlayList ; } if(m_vWidget!=nullptr) delete m_vWidget ; // if(mPlayer!=nullptr) // delete mPlayer; // if(openGLWidget!=nullptr) // delete openGLWidget; } void eMovie::init(bool bPlay) { QString file = m_attr.path + MACRO_FENGEFU + m_attr.name; file.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN); QFile fFile(file); if(fFile.exists()) { //alahover 20111111 -s // av_register_all(); /**初始化FFMPEG 调用了这个才能正常使用编码器和解码器**/ // avformat_network_init(); /**支持打开网络文件**/ // /**SDL初始化**/ // if (SDL_Init(SDL_INIT_AUDIO)) // { // fprintf(stderr,"Could not initialize SDL - %s. \n", SDL_GetError()); // exit(1); // } // mPlayer = new VideoPlayer; // openGLWidget = new glyuvwidget(nullptr); // openGLWidget->setGeometry(0,0,200,200); // connect(mPlayer,SIGNAL(sigYuv_liuyi(uchar*,uint,uint)),this,SLOT(slotShowYuv_liuyi(uchar*,uint,uint))); // mPlayer->stop(true); //如果在播放则先停止 // //这里需要再等待一段时间,目的是为了让解析视频的线程执行完成能够退出 // QEventLoop eventloop; // QTimer::singleShot(100, &eventloop, SLOT(quit())); // eventloop.exec(); // mPlayer->setFileName(file);// // mPlayer->play(); // return; //alahover 20111111 -o m_vPlayer = new QMediaPlayer(this); m_vPlayList = new QMediaPlaylist(this); m_vWidget = new QGraphicsVideoItem(this); m_vWidget->setFlag(QGraphicsItem::ItemStacksBehindParent); //m_vWidget->setFlag(QGraphicsItem::ItemIgnoresParentOpacity); //QGraphicsItem::stackBefore() m_vWidget->setAspectRatioMode(static_cast(m_attr.aspectRatioMode)); m_vPlayList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop); m_vPlayer->setMuted(false); m_vPlayer->setPlaylist(m_vPlayList); m_vPlayer->setVideoOutput(m_vWidget); connect(this, SIGNAL(rectChanged(const QRectF &)), this, SLOT(onAdjustMovieRect())); onAdjustMovieRect(); if(!bPlay) { playElectment(); stopElectment(); } } } //void eMovie::slotShowYuv_liuyi(uchar *ptr, uint width, uint height) //{ // openGLWidget->slotShowYuv(ptr,width,height); //} void eMovie::setElement(const QJsonObject &json, Data &attr) { attr.name = json["widget"]["file"].toString(); attr.path = json["widget"]["path"].toString(); attr.strRawName = json["widget"]["fileRaw"].toString(); attr.strRawPath = json["widget"]["pathRaw"].toString(); attr.aspectRatioMode = json["play"]["aspectRatioMode"].toInt(); attr.playDuration = json["play"]["playDuration"].toInt(); attr.playTimes = json["play"]["playTimes"].toInt(); } QWidget* eMovie::wAttr() { QWidget *wObj = eObject::wAttr(); QWidget *w = wAttrElement(); static_cast(w->layout())->insertWidget(0, wObj); return w; } QWidget* eMovie::wAttrElement() { eMovieAttr *w = new eMovieAttr(m_attr); connect(w, SIGNAL(sResChanged(const QString &,const QString &)), this, SLOT(onResChanged(const QString &,const QString &))); connect(w, SIGNAL(sAttrChanged(const eMovie::Data &)), this, SLOT(onAttrChanged(const eMovie::Data &))); return w; } QJsonObject eMovie::save(const QString &pRoot) { QString file0 = m_attr.path + PAGEDEL_SUFFIX + MACRO_FENGEFU + m_attr.name; QString file1 = m_attr.path + MACRO_FENGEFU + m_attr.name; QFile f0(file0); QFile f1(file1); QString old_file; QString new_file = pRoot + MACRO_FENGEFU + m_attr.name; if(f0.exists()) { old_file = file0; } else if(f1.exists()) { old_file = file1; } else { return QJsonObject(); } QFile old_f(old_file); QFile new_f(new_file); if(!new_f.exists()) old_f.copy(new_file); m_attr.path = pRoot; return elementJson(); } QStringList eMovie::filesList() const { QStringList list; list.append(m_attr.path + MACRO_FENGEFU + m_attr.name); return list; } QJsonObject eMovie::elementJson() const { QJsonObject oRoot; QJsonObject oWidget; QJsonObject oPlay; // Interior oRoot["elementType"] = "Movie"; oRoot["elementTypeId"] = type(); oRoot["geometry"] = eObject::elementJson(); // Widget oWidget["file"] = m_attr.name; QString strtempPath=m_attr.path; strtempPath.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN); oWidget["path"] = strtempPath; oWidget["fileRaw"] = m_attr.strRawName; QString strtempRawPath=m_attr.strRawPath; strtempRawPath.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN); oWidget["pathRaw"] = strtempRawPath; oRoot["widget"] = oWidget; // Play oPlay["aspectRatioMode"] = m_attr.aspectRatioMode; oPlay["playDuration"] = m_attr.playDuration; oPlay["playTimes"] = m_attr.playTimes; oRoot["play"] = oPlay; return oRoot; } void eMovie::playElectment() { QString file = m_attr.path + MACRO_FENGEFU + m_attr.name; file.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN); QFile fFile(file); if(fFile.exists()) { m_vPlayList->clear(); m_vPlayList->addMedia(QUrl(file)); m_vPlayList->setCurrentIndex(0); m_vPlayer->stop(); m_vPlayer->play(); } } void eMovie::stopElectment() { if(m_vPlayer!=nullptr) { if(m_vPlayer->isAvailable()) { m_vPlayer->pause(); // m_vPlayer->stop(); //m_vPlayList->clear(); } } } void eMovie::onResChanged(const QString &file,const QString &RawFile) { QFileInfo fi(file); m_attr.name = fi.fileName(); m_attr.path = fi.absolutePath(); QFileInfo fiRaw(RawFile); m_attr.strRawName = fiRaw.fileName(); m_attr.strRawPath = fiRaw.absolutePath(); stopElectment(); playElectment(); } void eMovie::onAttrChanged(const eMovie::Data &data) { m_attr.playDuration=data.playDuration; m_attr.playTimes=data.playTimes; m_attr.aspectRatioMode=data.aspectRatioMode; setPlayArg(data.aspectRatioMode, data.playDuration, data.playTimes); m_vWidget->setAspectRatioMode(static_cast(m_attr.aspectRatioMode)); } void eMovie::onAdjustMovieRect() { if(m_vWidget!=nullptr) m_vWidget->setSize(QSizeF(rect().width(), rect().height())); // if(m_vffmpegWidget!=nullptr) // m_vffmpegWidget->setGeometry(rect()); } void eMovie::setPlayArg(int armode, int pd, int pt) { m_attr.aspectRatioMode = armode; m_attr.playDuration = pd; m_attr.playTimes = pt; } void eMovie::Delay(int msec) { QTime dieTime = QTime::currentTime().addMSecs(msec); while( QTime::currentTime() < dieTime ) QCoreApplication::processEvents(QEventLoop::AllEvents, 100); } void eMovie::InitFfmpegSdl() { // m_vffmpegWidget = new QGraphicsProxyWidget(this); // m_vffmpegWidget->setFlag(QGraphicsItem::ItemStacksBehindParent); // QFfWidget *label = new QFfWidget(); // label->show(); // m_vffmpegWidget->setWidget(label); // m_vffmpegWidget->setMinimumSize(0, 0); // connect(this, SIGNAL(rectChanged(const QRectF &)), this, SLOT(onAdjustMovieRect())); // onAdjustMovieRect(); } double eMovie::GetVideoTimeRawSpan(QString strFilePathName) { AVFormatContext *pFormatCtx; std::string str = strFilePathName.toStdString(); const char* filepath = str.c_str(); //char filepath[] = "G:\\taxiAd.mp4"; //初始化编解码库 av_register_all();//创建AVFormatContext对象,与码流相关的结构。 pFormatCtx = avformat_alloc_context(); //初始化pFormatCtx结构 if (avformat_open_input(&pFormatCtx, filepath, nullptr, nullptr) != 0){ printf("Couldn't open input stream.\n"); return -1; } //获取音视频流数据信息 if (avformat_find_stream_info(pFormatCtx, nullptr) < 0){ printf("Couldn't find stream information.\n"); return -1; } //nb_streams视音频流的个数,这里当查找到视频流时就中断了。 unsigned int iVideoStreamIndex=0; for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++) { if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO){ iVideoStreamIndex=i; } } AVStream *videoStream = pFormatCtx->streams[iVideoStreamIndex]; double totalSeconds = videoStream->duration * av_q2d(videoStream->time_base); printf("totalSeconds = %lf\n", totalSeconds); qreal iw= pFormatCtx->streams[iVideoStreamIndex]->codecpar->width ; qreal ih=pFormatCtx->streams[iVideoStreamIndex]->codecpar->height ; qDebug()<<"宽"<10) break; } } QFileInfo tempFileInfo(strOutFilePathName); if(tempFileInfo.exists()) { return strOutFilePathName; } else { LoAppConfig *cfg = LoAppConfig::getInstance(); if(strFile.right(4)==".mp4") { QSettings *settings = new QSettings(cfg->OrganizationName(), cfg->ApplicationName()); if(settings->value("videoconvert").isValid()) { if(settings->value("videoconvert").toBool()) { process = new QProcess(nullptr); QStringList args;//=getArguments(strFile,"f://abc.mp4"); args<<"-y"; args<<"-i"<setWorkingDirectory(strAppPath); connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(continueConvert(int,QProcess::ExitStatus))); connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(outputCommand())); connect(process,SIGNAL(readyReadStandardError()),this,SLOT(outputCommand())); process->start("ffmpeg",args); // m_pConverProgressTimer = new QTimer(this); // connect(m_pConverProgressTimer,SIGNAL(timeout()),this,SLOT(onConverProgress())); // m_strOutFilePathName=strOutFilePathName; // m_pConverProgressTimer->start(1000); //connect(m_pGetAskTimer,SIGNAL(timeout()),m_pProgressConvertVideo,SLOT(TimerOutUnlock())); connect(this, SIGNAL(sigSetTipTextContent ( QString )), m_pProgressConvertVideo, SLOT( SetTipTextContent(QString))); m_pProgressConvertVideo->lock(tr("Convert video"),tr("Success"),tr("Convert video")+tr("failed")); // m_pGetAskTimer->start(3000); m_pProgressConvertVideo->exec(); return strOutFilePathName; } else { QFile::copy(strFile, strOutFilePathName); return strOutFilePathName; } } else { QFile::copy(strFile, strOutFilePathName); return strOutFilePathName; } } else { process = new QProcess(nullptr); QStringList args;//=getArguments(strFile,"f://abc.mp4"); args<<"-y"; args<<"-i"<setWorkingDirectory(strAppPath); connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(continueConvert(int,QProcess::ExitStatus))); connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(outputCommand())); connect(process,SIGNAL(readyReadStandardError()),this,SLOT(outputCommand())); process->start("ffmpeg",args); // m_pConverProgressTimer = new QTimer(this); // connect(m_pConverProgressTimer,SIGNAL(timeout()),this,SLOT(onConverProgress())); // m_strOutFilePathName=strOutFilePathName; // m_pConverProgressTimer->start(1000); //connect(m_pGetAskTimer,SIGNAL(timeout()),m_pProgressConvertVideo,SLOT(TimerOutUnlock())); connect(this, SIGNAL(sigSetTipTextContent ( QString )), m_pProgressConvertVideo, SLOT( SetTipTextContent(QString))); m_pProgressConvertVideo->lock(tr("Convert video"),tr("Success"),tr("Convert video")+tr("failed")); // m_pGetAskTimer->start(3000); m_pProgressConvertVideo->exec(); return strOutFilePathName; } // QSettings *settings = new QSettings(cfg->OrganizationName(), cfg->ApplicationName()); // if(settings->value("videoconvert").isValid()) // { // if(settings->value("videoconvert").toBool()) // { // process = new QProcess(nullptr); // QStringList args;//=getArguments(strFile,"f://abc.mp4"); // args<<"-y"; // args<<"-i"<setWorkingDirectory(strAppPath); // connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(continueConvert(int,QProcess::ExitStatus))); // connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(outputCommand())); // connect(process,SIGNAL(readyReadStandardError()),this,SLOT(outputCommand())); // process->start("ffmpeg",args); //// m_pConverProgressTimer = new QTimer(this); //// connect(m_pConverProgressTimer,SIGNAL(timeout()),this,SLOT(onConverProgress())); //// m_strOutFilePathName=strOutFilePathName; //// m_pConverProgressTimer->start(1000); // //connect(m_pGetAskTimer,SIGNAL(timeout()),m_pProgressConvertVideo,SLOT(TimerOutUnlock())); // m_pProgressConvertVideo->lock(tr("Convert video"),tr("Success"),tr("Convert video")+tr("failed")); // // m_pGetAskTimer->start(3000); // m_pProgressConvertVideo->exec(); // return strOutFilePathName; // } // else { // QFile::copy(strFile, strOutFilePathName); // return strOutFilePathName; // } // } // else { // QFile::copy(strFile, strOutFilePathName); // return strOutFilePathName; // } } } QString eMovie::ConvertVideoFormat(QString strFile) { QFileInfo tmpFile(strFile); //QString strOutFileOnlyTitle=tmpFile.fileName().left(tmpFile.fileName().length()-tmpFile.suffix().length()-1); QString file_full=strFile.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN); QString strFileMD5=getFileMd5(file_full); QString strOutFileOnlyTitle=strFileMD5; QString strOutFilePathName=m_globalstrSavePath+MACRO_FENGEFU+strOutFileOnlyTitle+".mp4"; strOutFilePathName.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN); int iReTryCount=0; QDir dRoot; while(!dRoot.mkdir(m_globalstrSavePath)) { QThread::sleep(1); iReTryCount++; if(iReTryCount>10) break; } QFileInfo tempFileInfo(strOutFilePathName); if(tempFileInfo.exists()) { return strOutFilePathName; } else { LoAppConfig *cfg = LoAppConfig::getInstance(); QSettings *settings = new QSettings(cfg->OrganizationName(), cfg->ApplicationName()); if(settings->value("videoconvert").isValid()) { if(settings->value("videoconvert").toBool()) { QString strVideoRect=""; QString strEncodeExePath=""; QString strAppPath=QApplication::applicationDirPath(); strAppPath.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN); strEncodeExePath="\""+strAppPath+"/ffmpeg.exe\" "; QString strSoundEncode=""; strSoundEncode=" -acodec mp3 -ar 44100"; QString strVideoEncode=""; QString strEncodeRate=""; QString strFrameRate=""; QString strCommandLine=""; QString strStart=""; QString strEnd=""; strVideoEncode=" -vcodec mpeg4"; //264 // strEncodeRate.Format(" -b %d",m_intEncodeRate); // strVideoEncode=_T(" -vcodec h264"); // strFrameRate.Format(" -r %d",m_intFrameRate); //strCommandLine=strEncodeExePath+"-y -i \""+file_full+"\""+strVideoEncode+" \""+strOutFilePathName+"\""; //strCommandLine="-y -i \""+file_full+"\""+strVideoEncode+" \""+strOutFilePathName+"\""; strCommandLine="-y -i "+file_full+strVideoEncode+" "+strOutFilePathName; QString strCommandLastString=strCommandLine; qDebug()<setWorkingDirectory(strAppPath); connect(process,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(continueConvert(int,QProcess::ExitStatus))); process->start(strEncodeExePath,args); m_pProgressConvertVideo = new LoEmptyDialog(); m_pProgressConvertVideo->lock(tr("Convert video"),tr("Success"),tr("Convert video")+tr("failed")); m_pProgressConvertVideo->exec(); // QString filebat=strAppPath+"/convertvideo.bat"; // filebat.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN); // QFile file(filebat); // file.setFileName(filebat); // file.open(QIODevice::WriteOnly); //文件以只写方式打开 // QString str = strCommandLine; //将文本编辑框中的内容送给str // file.write(str.toUtf8()); // file.close(); // QProcess p(nullptr); // p.setWorkingDirectory(strAppPath); // QString command = filebat; // p.start(command); // m_pConverProgressTimer = new QTimer(this); // connect(m_pConverProgressTimer,SIGNAL(timeout()),this,SLOT(onConverProgress())); // m_pConverProgressTimer->start(1000); // connect(&p,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(continueConvert(int,QProcess::ExitStatus))); // if(p.waitForFinished()){ //等待脚本运行完成,超时时间默认是3000s,超时返回0,正常返回1 // //strInfo = "完成!"; // }else{ // // strInfo = "bat运行错误!"; // } return strOutFilePathName; } else { QFile::copy(strFile, strOutFilePathName); return strOutFilePathName; } } else { QFile::copy(strFile, strOutFilePathName); return strOutFilePathName; } } } void eMovie::onConverProgress() { if(!m_strOutFilePathName.isEmpty()) { QFile ff(m_strOutFilePathName); if(ff.exists()) { m_pProgressConvertVideo->unlock(); m_pConverProgressTimer->stop(); delete m_pConverProgressTimer; } } // int i=0; // if(iEncodeType==1) // { // i=GetConvertFileIsOK(m_strCurConvertOkFilePathName); // } // else // i=GetConvertDirFilesNumber(PATH_CONVERT_OUTPUT_PATH,"success"); // static int iNotJinduValue=0; // QString striNotJinduValue=QString::number(iNotJinduValue); // if(iNotJinduValue<100) // m_pProgressConvertVideo->SetTipTextContent(striNotJinduValue); // { // QString strTempFileName=m_strOutputPath+"."+"mp4"; // DWORD dwAttr = GetFileAttributes(strTempFileName); // if(dwAttr == 0xFFFFFFFF) //文件夹不存在 // { // } // else // { // m_outFileSizeValue=MyGetFileSize(strTempFileName); // QString strtemp=FormatByteCount1(m_outFileSizeValue); // strtemp="["+strtemp+"]"; // m_pProgressConvertVideo->SetTipTextContent(strtemp+MESSAGE_CONVERTING_VIDEO); // } // } // iNotJinduValue++; // if(iNotJinduValue==99) // { // iNotJinduValue=0; // m_iVideoPi++; // QString strtemp=FormatByteCount1(m_outFileSizeValue); // strtemp="["+strtemp+"]"; // m_pProgressConvertVideo->SetTipTextContent(strtemp+MESSAGE_CONVERTING_VIDEO); // } // m_pProgressConvertVideo->unlock(); } void eMovie::continueConvert(int i,QProcess::ExitStatus) { Q_UNUSED(i); m_pProgressConvertVideo->unlock(); } void eMovie::outputCommand(){ QByteArray cmdoutput = process->readAllStandardOutput(); char *t=cmdoutput.data(); QString txtoutput=QString::fromLocal8Bit(t); // qDebug()<<"\r\nStandardOut:"<readAllStandardError(); t=cmdoutput.data(); txtoutput=QString::fromLocal8Bit(t); // qDebug()<<"\r\nerror:"<readAllStandardError();//readAllStandardOutput(); // char *t=cmdoutput.data(); // QString txtoutput=QString::fromLocal8Bit(t); // qDebug()<<"error:"<readAllStandardError(); char *t=cmdoutput.data(); QString txtoutput=QString::fromLocal8Bit(t); qDebug()<<"\r\nerror:"<isAvailable()) { //m_vPlayer->pause(); m_vPlayer->stop(); m_vPlayList->clear(); } } QFile file(m_attr.path+"/"+m_attr.name); if(file.exists()) file.remove(); }