#include "emovieattr.h"
#include "ui_emovieattr.h"
#include "emovie.h"
#include <QSettings>
#include <QThread>
extern "C"{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
}
eMovieAttr::eMovieAttr(const eMovie::Data &data, QWidget *parent) :
    eAttr(parent),
    ui(new Ui::eMovieAttr)
{
    ui->setupUi(this);

    ui->wFile           ->setText        (data.strRawName);
    ui->wAspectRatioMode->setCurrentIndex(data.aspectRatioMode);
    ui->wPlayDuration   ->setValue       (data.playDuration);
    ui->wPlayTimes      ->setValue       (data.playTimes);
    m_strOldSuiCaiFile=data.name;
    m_strOldSuiCaiPath=data.path;

    connect(ui->wAspectRatioMode, SIGNAL(currentIndexChanged(int)), this, SLOT(onAttrChanged()));
    connect(ui->wPlayDuration,    SIGNAL(valueChanged(int)),        this, SLOT(onAttrChanged()));
    connect(ui->wPlayTimes,       SIGNAL(valueChanged(int)),        this, SLOT(onAttrChanged()));
    connect(ui->bnSelectFile,     SIGNAL(clicked(bool)),            this, SLOT(onSelectFile()));
    ui->label_8->setVisible(false);
    ui->wAspectRatioMode->setVisible(false);
}

eMovieAttr::~eMovieAttr()
{
    delete ui;
}

void eMovieAttr::onSelectFile()
{
    QString file = LoAppTools::getInstance()->selectFile(eMovie::filters(), this,true);
    if(!file.isNull()) {
        QString strOutFile=ConvertVideoFormatByFFmpeg(file);
        QFileInfo outfi(strOutFile);
        ui->wFile->setText(QFileInfo(file).fileName());



//alahover 20211115 alahover test sdl ffmpeg
//        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;
//        myopenGLWidget=new glyuvwidget(this);
//        myopenGLWidget->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;
        int iSecs=GetVideoTimeRawSpan(strOutFile);
        ui->wPlayDuration->setValue(iSecs);
        emit sResChanged(strOutFile,file);
        QString strOldFile=m_strOldSuiCaiPath+"/"+m_strOldSuiCaiFile;
        QFile fileOld(strOldFile);
        if(fileOld.exists())
        {
            fileOld.remove();
        }
        QFileInfo fi(strOutFile);
        m_strOldSuiCaiFile = fi.fileName();
        m_strOldSuiCaiPath = fi.absolutePath();

    }
}
double eMovieAttr::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()<<"宽"<<QString::number(iw);
    qDebug()<<"高"<<QString::number(ih);
//    if(iw!=0)
//        m_display_aspect_ratio=ih/iw;



    avformat_close_input(&pFormatCtx);
    return totalSeconds;
}
void eMovieAttr::slotShowYuv_liuyi(uchar *ptr, uint width, uint height)
{
    //if(!m_bStop)//如果点击停止按钮，则不再刷新图片
    {
        //ui->openGLWidget->slotShowYuv(ptr,width,height);
        //myopenGLWidget->slotShowYuv(ptr,width,height);
    }
}
QString eMovieAttr::getFileMd5(QString filePath)
{
    QFile localFile(filePath);

    if (!localFile.open(QFile::ReadOnly))
    {
        qDebug() << "file open error.";
        return 0;
    }

    QCryptographicHash ch(QCryptographicHash::Md5);

    quint64 totalBytes = 0;
    quint64 bytesWritten = 0;
    quint64 bytesToWrite = 0;
    quint64 loadSize = 1024 * 4;
    QByteArray buf;

    totalBytes = localFile.size();
    bytesToWrite = totalBytes;

    while (1)
    {
        if(bytesToWrite > 0)
        {
            buf = localFile.read(qMin(bytesToWrite, loadSize));
            ch.addData(buf);
            bytesWritten += buf.length();
            bytesToWrite -= buf.length();
            buf.resize(0);
        }
        else
        {
            break;
        }

        if(bytesWritten == totalBytes)
        {
            break;
        }
    }


    localFile.close();
    QByteArray md5 = ch.result();
    QString strRes="";
    strRes.append(md5.toHex());
    return strRes;
}
QString eMovieAttr::ConvertVideoFormatByFFmpeg(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;
   QDir drr(m_globalstrSavePath);
   if(!drr.exists())
   {
       while(!dRoot.mkdir(m_globalstrSavePath))
       {
           QThread::sleep(1);
           iReTryCount++;

           if(drr.exists())
               break;
           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())
           {
               process = new QProcess(nullptr);
                   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()));

               QStringList args;//=getArguments(strFile,"f://abc.mp4");
               args<<"-y";
               args<<"-i"<<file_full;
               args<<"-vcodec"<<"h264";
               QString strtempstrOutFilePathName=strOutFilePathName;
               args<<strtempstrOutFilePathName;
               m_pProgressConvertVideo = new LoEmptyDialog();
               QString strAppPath=QApplication::applicationDirPath();
               strAppPath.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN);
               process->setWorkingDirectory(strAppPath);

               process->start("ffmpeg",args);

               //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;

       }
   }


}
QString eMovieAttr::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";
        QFileInfo tempFileInfo(strOutFilePathName);
        if(tempFileInfo.exists())
        {
            return strOutFilePathName;
        }
        else {
            process = new QProcess(this);
                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()));

            QStringList args;//=getArguments(strFile,"f://abc.mp4");
            args<<"-y";
            args<<"-i"<<strFile;
            args<<"-vcodec"<<"h264";
            args<<strOutFilePathName;
            process->start("ffmpeg",args);
            m_pProgressConvertVideo = new LoEmptyDialog();
            //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;
        }


}

void eMovieAttr::continueConvert(int i,QProcess::ExitStatus)
{
    //int aa=i;
    m_pProgressConvertVideo->unlock();
}
void eMovieAttr::outputCommand(){
    QByteArray cmdoutput = process->readAllStandardOutput();
    char *t=cmdoutput.data();
    QString txtoutput=QString::fromLocal8Bit(t);
    qDebug()<<txtoutput;
    cmdoutput = process->readAllStandardError();
    t=cmdoutput.data();
    txtoutput=QString::fromLocal8Bit(t);
    qDebug()<<txtoutput;
    if(txtoutput.contains("Duration: "))
    {
        QString strDuration=txtoutput.mid(txtoutput.indexOf("Duration: ")+10,11)+"0";
        qDebug()<<"Duration="<<strDuration;

        QTime aa=QTime::fromString(strDuration,TIME_STRING_FORMAT);
        QTime bb(0,0,0);
        m_videoTimeLong=bb.secsTo(aa);
    }
    if(txtoutput.contains("time="))
    {
        QString strTime=txtoutput.mid(txtoutput.indexOf("time=")+5,11)+"0";
        qDebug()<<"time="<<strTime;
        QTime aa=QTime::fromString(strTime,TIME_STRING_FORMAT);
        QTime bb(0,0,0);
        int iJinDuTime=bb.secsTo(aa);
        if(m_videoTimeLong>0)
        {
            int iJindu=iJinDuTime*100/m_videoTimeLong;
            qDebug()<<"进度="<<iJindu;
            QString strJindu=QString::number(iJindu)+"%";
            emit sigSetTipTextContent(tr("Converting format")+strJindu);

        }

    }
}

QStringList eMovieAttr::getArguments(QString filepath,QString output){
    QStringList args;

    args << "-i" << filepath;
    args << "-vcodec" <<"libx264";
//    if(ui->comboBox_vcodec->currentIndex()!=2){
//        args << "-vcodec" << ui->comboBox_vcodec->currentText();
//    }
    args << "-b:v" << "2000k";
//    switch(ui->comboBox_videoQuality->currentIndex()){
//    case 0:args << "-b:v" << "2000k";break;
//    case 1:args << "-b:v" << "1000k";break;
//    case 2:args << "-b:v" << "500k";break;
//    case 3:args << "-b:v" << "250k";break;
//    case 4:args << "-b:v" << ui->lineEdit_videoQuality->text();break;
//    }

    args << "-s" << "800x600";
//    args << "-s" << ui->comboBox_videoScale->currentText();

//    if(ui->checkBox_hasWatermark->isChecked()){
//        args << "-vf" << tr("movie=%1[logo];[in][logo] overlay=%2:%3 [out]").arg(QFileInfo(ui->lineEdit_watermarkPath->text()).fileName())
//                .arg(ui->lineEdit_watermark_x->text())
//                .arg(ui->lineEdit_watermark_y->text());
//    }
    //args << "-acodec" << "libvo_aacenc";
    args <<"-c:a aac";
//    if(ui->comboBox_audioCodec->currentIndex()!=2)
//        args << "-acodec" << ui->comboBox_audioCodec->currentText();
//    args << "-b:a" << "64k";
//    switch(ui->comboBox_audioQuality->currentIndex()){
//        case 0:args << "-b:a" << "256k";break;
//        case 1:args << "-b:a" << "192k";break;
//        case 2:args << "-b:a" << "125k";break;
//        case 3:args << "-b:a" << "96k";break;
//        case 4:args << "-b:a" << ui->lineEdit_audioQuality->text();break;
//        }
    args << "-ac" << "2";
//    args << "-ac" << QString::number(ui->comboBox_audioChannel->currentIndex()+1);
    args << "-ar" <<"44100";
//    args << "-ar" << ui->comboBox_audioRate->currentText();

    args << "-y";

//    QString output=ui->lineEdit_mainOutputPath->text()
//                   +filepath.right(filepath.count()-ui->lineEdit_mainSourcePath->text().count());
//    output=output.left(output.count()-3)+ui->comboBox_convertTo->currentText();
    QDir outputPath;outputPath.mkpath(QFileInfo(output).absolutePath());
    args << output;
    qDebug() << args << endl;
    return args;
}
void eMovieAttr::onAttrChanged()
{
    eMovie::Data data;
    data.aspectRatioMode = ui->wAspectRatioMode->currentIndex();
    data.playDuration    = ui->wPlayDuration->value();
    data.playTimes       = ui->wPlayTimes->value();
    emit sAttrChanged(data);
}
