[vlc-devel] [PATCH] Adds batch convert support to the VLC GUI.

Jean-Baptiste Kempf jb at videolan.org
Fri Nov 28 12:32:58 CET 2014


Hello,

This was applied, thanks.

With a minor change.

On 11 Nov, Lochlin Duperron wrote :
> This commit modifies the convert wizard to accept multiple files from the file dialog box
> The GUI should operate the same when a single file is selected (providing an option of where and what to name the file), but when multiple files are selected the files are
> placed into the same folder with the same name and a new extention (there is an option to append -converted if you are converting to the same extention).
> There are some tooltips to explain this operation.
> 
> Most of the changes are pretty straight-forward, converting QStrings to QStringLists and passing the full list of MRLs around.  The playlist already supports the batch processing
> in a pretty straightforward way, so there's no issues there.
> 
> StandardPanel.cpp was modified to create a temp QStringList for passing to the streamingDialog, as it now takes the full list of input files rather than just one
> 
> Convert.cpp/hpp modified to take the QStringList and to behave (semi)-intelligently when reciving multiple files
> open.cpp modified to pass the MRLs rather than MRL[0]
> and the Dialogs_provider.cpp/hpp to pass the MRLs along, pretty much.  It also clears the playlist when recieving a list and starts the playlist from the beginning when it's added all the files to be converted.
> ---
>  .../gui/qt4/components/playlist/standardpanel.cpp  |  12 ++-
>  modules/gui/qt4/dialogs/convert.cpp                | 120 ++++++++++++++++-----
>  modules/gui/qt4/dialogs/convert.hpp                |  12 ++-
>  modules/gui/qt4/dialogs/open.cpp                   |  19 +++-
>  modules/gui/qt4/dialogs_provider.cpp               |  45 ++++++--
>  modules/gui/qt4/dialogs_provider.hpp               |   2 +-
>  6 files changed, 164 insertions(+), 46 deletions(-)
> 
> diff --git a/modules/gui/qt4/components/playlist/standardpanel.cpp b/modules/gui/qt4/components/playlist/standardpanel.cpp
> index 38de867..eb99f1b 100644
> --- a/modules/gui/qt4/components/playlist/standardpanel.cpp
> +++ b/modules/gui/qt4/components/playlist/standardpanel.cpp
> @@ -319,14 +319,22 @@ void StandardPLPanel::popupAction( QAction *action )
>          /* locally handled only */
>          temp = model->getURI( index );
>          if ( ! temp.isEmpty() )
> -            THEDP->streamingDialog( NULL, temp, false );
> +        {
> +            QStringList tempList;
> +            tempList.append(temp);
> +            THEDP->streamingDialog( NULL, tempList, false );
> +        }
>          break;
>  
>      case VLCModelSubInterface::ACTION_SAVE:
>          /* locally handled only */
>          temp = model->getURI( index );
>          if ( ! temp.isEmpty() )
> -            THEDP->streamingDialog( NULL, temp );
> +        {
> +            QStringList tempList;
> +            tempList.append(temp);
> +            THEDP->streamingDialog( NULL, tempList );
> +        }
>          break;
>  
>      case VLCModelSubInterface::ACTION_CREATENODE:
> diff --git a/modules/gui/qt4/dialogs/convert.cpp b/modules/gui/qt4/dialogs/convert.cpp
> index 2674928..5a7bcee 100644
> --- a/modules/gui/qt4/dialogs/convert.cpp
> +++ b/modules/gui/qt4/dialogs/convert.cpp
> @@ -38,7 +38,7 @@
>  #include <QCheckBox>
>  
>  ConvertDialog::ConvertDialog( QWidget *parent, intf_thread_t *_p_intf,
> -                              const QString& inputMRL )
> +                              const QStringList& inputMRLs )
>                : QVLCDialog( parent, _p_intf )
>  {
>      setWindowTitle( qtr( "Convert" ) );
> @@ -46,7 +46,18 @@ ConvertDialog::ConvertDialog( QWidget *parent, intf_thread_t *_p_intf,
>  
>      QGridLayout *mainLayout = new QGridLayout( this );
>      SoutInputBox *inputBox = new SoutInputBox( this );
> -    inputBox->setMRL( inputMRL );
> +    incomingMRLs = &inputMRLs;
> +
> +    singleFileSelected = (inputMRLs.length() == 1);
> +
> +    if(singleFileSelected)
> +    {
> +        inputBox->setMRL( inputMRLs[0] );
> +    }
> +    else
> +    {
> +        inputBox->setMRL("Multiple files selected.");
> +    }
>      mainLayout->addWidget( inputBox, 0, 0, 1, -1  );
>  
>      /**
> @@ -62,12 +73,26 @@ ConvertDialog::ConvertDialog( QWidget *parent, intf_thread_t *_p_intf,
>      fileLine->setMinimumWidth( 300 );
>      fileLine->setFocus( Qt::ActiveWindowFocusReason );
>      destLabel->setBuddy( fileLine );
> +    // You can set a specific name for only one file.
> +    if(singleFileSelected)
> +    {
> +        QPushButton *fileSelectButton = new QPushButton( qtr( "Browse" ) );
> +        destLayout->addWidget( fileSelectButton, 0, 2);
> +        BUTTONACT( fileSelectButton, fileBrowse() );
> +    }
>  
> -    QPushButton *fileSelectButton = new QPushButton( qtr( "Browse" ) );
> -    destLayout->addWidget( fileLine, 0, 1 );
> -    destLayout->addWidget( fileSelectButton, 0, 2);
> -    BUTTONACT( fileSelectButton, fileBrowse() );
> +    // but multiple files follow a naming convention
> +    else
> +    {
> +        fileLine->setText("Multiple Files Selected.");
> +        fileLine->setReadOnly(true);
> +        fileLine->setToolTip("Files will be placed in the same directory "
> +                "with the same name.");
>  
> +        appendBox = new QCheckBox( qtr( "Append '-converted' to filename" ) );
> +        destLayout->addWidget( appendBox, 1, 0 );
> +    }
> +    destLayout->addWidget( fileLine, 0, 1 );
>      mainLayout->addWidget( destBox, 3, 0, 1, -1  );
>  
>  
> @@ -147,29 +172,74 @@ void ConvertDialog::close()
>  {
>      hide();
>  
> -    if( dumpRadio->isChecked() )
> -    {
> -        mrl = "demux=dump :demuxdump-file=" + fileLine->text();
> -    }
> -    else
> +    for(int i = 0; i < incomingMRLs->length(); i++)
>      {
> -        mrl = "sout=#" + profile->getTranscode();
> -        if( deinterBox->isChecked() )
> +        QString mrl;
> +
> +        if( dumpRadio->isChecked() )
>          {
> -            mrl.remove( '}' );
> -            mrl += ",deinterlace}";
> +            mrl = "demux=dump :demuxdump-file=" + fileLine->text();
>          }
> -        mrl += ":";
> -        if( displayBox->isChecked() )
> -            mrl += "duplicate{dst=display,dst=";
> -        mrl += "std{access=file{no-overwrite},mux=" + profile->getMux()
> -             + ",dst='" + fileLine->text().replace( QChar('\''), "\\\'" )
> -             + "'}";
> -        if( displayBox->isChecked() )
> -            mrl += "}";
> +        else
> +        {
> +            mrl = "sout=#" + profile->getTranscode();
> +            if( deinterBox->isChecked() )
> +            {
> +                mrl.remove( '}' );
> +                mrl += ",deinterlace}";
> +            }
> +            mrl += ":";
> +            if( displayBox->isChecked() )
> +            {
> +                mrl += "duplicate{dst=display,dst=";
> +            }
> +
> +            QString newFileName;
> +
> +            // Only one file, use the destination provided
> +            if(singleFileSelected)
> +            {
> +                newFileName = fileLine->text();
> +            }
> +
> +            // Multiple, use the convention.
> +            else
> +            {
> +                QString fileExtension = ( ! profile->isEnabled() ) ? ".*" : "." + profile->getMux();
> +
> +                newFileName = incomingMRLs->at(i);
> +
> +                // Remove the file:// from the front of our MRL
> +                newFileName = newFileName.remove(0,7);
> +
> +                // Remote the existing extention (if any)
> +                int extentionPos = newFileName.lastIndexOf('.');
> +                if(extentionPos >= 0)
> +                {
> +                    newFileName = newFileName.remove(extentionPos, newFileName.length() - extentionPos);
> +                }
> +
> +                // If we have multiple files (i.e. we have an appenBox) and it's checked
> +                if(!singleFileSelected && appendBox->isChecked())
> +                {
> +                    newFileName = newFileName.append("-converted");
> +                }
> +
> +                // Stick our new extention on
> +                newFileName = newFileName.append(fileExtension);
> +            }
> +
> +            newFileName.replace( QChar('\''), "\\\'" );
> +
> +            mrl += "std{access=file{no-overwrite},mux=" + profile->getMux()
> +                 + ",dst='" + newFileName
> +                 + "'}";
> +            if( displayBox->isChecked() )
> +                mrl += "}";
> +        }
> +        msg_Dbg( p_intf, "Transcode MRL: %s", qtu( mrl ) );
> +        mrls.append(mrl);
>      }
> -
> -    msg_Dbg( p_intf, "Transcode MRL: %s", qtu( mrl ) );
>      accept();
>  }
>  
> diff --git a/modules/gui/qt4/dialogs/convert.hpp b/modules/gui/qt4/dialogs/convert.hpp
> index 9a9727e..8b69c0b 100644
> --- a/modules/gui/qt4/dialogs/convert.hpp
> +++ b/modules/gui/qt4/dialogs/convert.hpp
> @@ -36,19 +36,23 @@ class ConvertDialog : public QVLCDialog
>  {
>      Q_OBJECT
>  public:
> -    ConvertDialog( QWidget *, intf_thread_t *, const QString& );
> +    ConvertDialog( QWidget *, intf_thread_t *, const QStringList& );
>      virtual ~ConvertDialog(){}
>  
> -    QString getMrl() {return mrl;}
> +    QStringList getMrls() {return mrls;}
>  
>  private:
>      QLineEdit *fileLine;
>  
> -    QCheckBox *displayBox, *deinterBox;
> +    QCheckBox *displayBox, *deinterBox, *appendBox;
>      QRadioButton *dumpRadio;
>      QPushButton *okButton;
>      VLCProfileSelector *profile;
> -    QString mrl;
> +
> +    const QStringList *incomingMRLs;
> +    bool singleFileSelected;
> +    QStringList mrls;
> +
>  private slots:
>      void close() Q_DECL_OVERRIDE;
>      void cancel() Q_DECL_OVERRIDE;
> diff --git a/modules/gui/qt4/dialogs/open.cpp b/modules/gui/qt4/dialogs/open.cpp
> index 56ea980..90c7949 100644
> --- a/modules/gui/qt4/dialogs/open.cpp
> +++ b/modules/gui/qt4/dialogs/open.cpp
> @@ -392,13 +392,24 @@ void OpenDialog::transcode()
>  
>  void OpenDialog::stream( bool b_transcode_only )
>  {
> -    QString soutMRL = getMRL( false );
> -    if( soutMRL.isEmpty() ) return;
> +//    QString soutMRL = getMRL( false );
> +//    if( soutMRL.isEmpty() ) return;
> +
> +    QStringList soutMRLS = getMRLs(false);
> +    if(soutMRLS.empty())
> +    {
> +        return;
> +    }
> +
>      toggleVisible();
>  
>      /* Dbg and send :D */
> -    msg_Dbg( p_intf, "MRL passed to the Sout: %s", qtu( soutMRL ) );
> -    THEDP->streamingDialog( this, soutMRL, b_transcode_only,
> +    msg_Dbg( p_intf, "MRL(s) passed to the Sout: %i", soutMRLS.length() );
> +    for(int i = 0; i < soutMRLS.length(); i++)
> +    {
> +        msg_Dbg( p_intf, "MRL(s) passed to the Sout: %s", qtu( soutMRLS[i] ) );
> +    }
> +    THEDP->streamingDialog( this, soutMRLS, b_transcode_only,
>                              getOptions().split( " :" ) );
>  }
>  
> diff --git a/modules/gui/qt4/dialogs_provider.cpp b/modules/gui/qt4/dialogs_provider.cpp
> index 7c3cf16..33cc010 100644
> --- a/modules/gui/qt4/dialogs_provider.cpp
> +++ b/modules/gui/qt4/dialogs_provider.cpp
> @@ -62,6 +62,7 @@
>  #include <QApplication>
>  #include <QSignalMapper>
>  #include <QFileDialog>
> +#include <matroska/c/libmatroska_t.h>
>  
>  #define I_OP_DIR_WINTITLE I_DIR_OR_FOLDER( N_("Open Directory"), \
>                                             N_("Open Folder") )
> @@ -689,20 +690,22 @@ void DialogsProvider::saveRecentsToPlaylist()
>   ****************************************************************************/
>  
>  void DialogsProvider::streamingDialog( QWidget *parent,
> -                                       const QString& mrl,
> +                                       const QStringList& mrls,
>                                         bool b_transcode_only,
>                                         QStringList options )
>  {
> -    QString soutoption;
> +    QStringList outputMRLs;
>  
>      /* Stream */
> +    // Does streaming multiple files make sense?  I suppose so, just stream one
> +    // after the other, but not at the moment.
>      if( !b_transcode_only )
>      {
> -        SoutDialog *s = new SoutDialog( parent, p_intf, mrl );
> +        SoutDialog *s = new SoutDialog( parent, p_intf, mrls[0] );
>          s->setAttribute( Qt::WA_QuitOnClose, false ); // See #4883
>          if( s->exec() == QDialog::Accepted )
>          {
> -            soutoption = s->getMrl();
> +            outputMRLs.append(s->getMrl());
>              delete s;
>          }
>          else
> @@ -711,11 +714,15 @@ void DialogsProvider::streamingDialog( QWidget *parent,
>          }
>      } else {
>      /* Convert */
> -        ConvertDialog *s = new ConvertDialog( parent, p_intf, mrl );
> +        ConvertDialog *s = new ConvertDialog( parent, p_intf, mrls );
>          s->setAttribute( Qt::WA_QuitOnClose, false ); // See #4883
>          if( s->exec() == QDialog::Accepted )
>          {
> -            soutoption = s->getMrl();
> +            /* Clear the playlist.  This is because we're going to be populating
> +               it */
> +            playlist_Clear( THEPL, pl_Unlocked );
> +
> +            outputMRLs = s->getMrls();
>              delete s;
>          }
>          else
> @@ -724,12 +731,30 @@ void DialogsProvider::streamingDialog( QWidget *parent,
>          }
>      }
>  
> -    /* Get SoutMRL */
> -    if( !soutoption.isEmpty() )
> +    /* Get SoutMRL(s) */
> +    if( !outputMRLs.isEmpty() )
>      {
> -        options += soutoption.split( " :");
> +        /* For all of our MRLs */
> +        for(int i = 0; i < outputMRLs.length(); i++)
> +        {
> +
> +            /* Duplicate the options list.  This is because we need to have a
> +             copy for every file we add to the playlist.*/
> +            QStringList optionsCopy;
> +            for(int j = 0; j < options.length(); j++)
> +            {
> +                optionsCopy.append(options[j]);
> +            }
> +
> +            optionsCopy+= outputMRLs[i].split( " :");
> +            QString title = "Converting " + mrls[i];
> +
> +            /* Add each file to convert to our playlist, making sure to not attempt to start playing it.*/
> +            Open::openMRLwithOptions( p_intf, mrls[i], &optionsCopy, false, true, _(title.toStdString().c_str()) );
> +        }
>  
> -        Open::openMRLwithOptions( p_intf, mrl, &options, true, true, _("Streaming") );
> +        /* Start the playlist from the beginning */
> +        playlist_Control(THEPL,PLAYLIST_PLAY,pl_Unlocked);
>      }
>  }
>  
> diff --git a/modules/gui/qt4/dialogs_provider.hpp b/modules/gui/qt4/dialogs_provider.hpp
> index 4327fcd..3b577d0 100644
> --- a/modules/gui/qt4/dialogs_provider.hpp
> +++ b/modules/gui/qt4/dialogs_provider.hpp
> @@ -160,7 +160,7 @@ public slots:
>      void PLOpenDir();
>      void PLAppendDir();
>  
> -    void streamingDialog( QWidget *parent, const QString& mrl, bool b_stream = true,
> +    void streamingDialog( QWidget *parent, const QStringList& mrls, bool b_stream = true,
>                            QStringList options = QStringList("") );
>      void openAndStreamingDialogs();
>      void openAndTranscodingDialogs();
> -- 
> 2.1.0
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel

-- 
With my kindest regards,

-- 
Jean-Baptiste Kempf
http://www.jbkempf.com/ - +33 672 704 734
Sent from my Electronic Device



More information about the vlc-devel mailing list