Nya
Nya

Reputation: 310

How can I use Qt to encrypt/decrypte/play a video?

I am looking for a way to encrypt an video file and then use decrypt it to ram and play it directly.

Upvotes: 1

Views: 965

Answers (2)

aep
aep

Reputation: 806

setMedia takes a QIOdevice as second argument:

  #include <QMediaPlayer>
  #include <QApplication>
  #include <QFile>
  int main(int argc, char ** argv)
  {
      QApplication app(argc,argv);
      QString fileName = app.arguments().at(1);

      QFile io(fileName);
      io.open(QFile::ReadOnly);

      QMediaPlayer player;

      player.setMedia(QUrl("test.mp3"), &io);
      player.play();

      return app.exec();
  }

but just in case you really mean QDataStream:

QDataStream is buffered io, QIODevice is direct io, they're not compatible, so you have to double buffer like this:

#include <QMediaPlayer>
#include <QApplication>
#include <QFile>
#include <QBuffer>
#include <QDataStream>
int main(int argc, char ** argv)
{
    QApplication app(argc,argv);
    QString fileName = app.arguments().at(1);

    // our double buffer
    QByteArray bufferSpace;

    // our stream on which we can put "media" data
    QDataStream stream(&bufferSpace, QIODevice::WriteOnly);

    // this is just demo data
    QFile io(fileName);
    io.open(QFile::ReadOnly);
    stream << io.readAll();

    // open an IO Device on our buffer
    QBuffer buffer(&bufferSpace);
    buffer.open(QBuffer::ReadOnly);

    // give the IO to the media player
    QMediaPlayer player;
    player.setMedia(QUrl("test.mp3"), &buffer);
    player.play();

    return app.exec();
}

edit

here's a faster version of that "crypto" code you posted without using a buffer for the entire file:

#include <QMediaPlayer>
#include <QApplication>
#include <QFile>
#include <QBuffer>
#include <QDataStream>

static const unsigned char key = 0xAB;
class MyFunnyCrypto : public QFile /*or subclass any other IO*/
{
protected:
    virtual qint64 readData(char *data, qint64 maxSize)
    {
        qint64 r = QFile::readData(data, maxSize);
        if (r > 0) {
            for (qint64 i = 0; i < r; i++) {
                data[i] = data[i]^key;
            }
        }
        return r;
    }

};


int main(int argc, char ** argv)
{
    QApplication app(argc,argv);
    QString fileName = app.arguments().at(1);


    MyFunnyCrypto io;
    io.setFileName(fileName);
    io.open(QFile::ReadOnly);

    // give the IO to the media player
    QMediaPlayer player;
    player.setMedia(QUrl("test.mp3"), &io);
    player.play();

    return app.exec();
}

Upvotes: 3

Nya
Nya

Reputation: 310

Thanks to @aep . It doesn't have anything to do with QDataStream, and it's quite simple. Encryption:

unsigned char key = 0xAB;
QFile file("test.mp3");
file.open(QIODevice::ReadOnly);
QByteArray byteArray = file.readAll();
for(int i=1024;i<byteArray.length();i++){
    byteArray[i] = byteArray[i]^key;
}
file.close();

QFile encrypted("encrypted.mp3");
encrypted.open(QIODevice::WriteOnly);
encrypted.write(byteArray);
encrypted.close();

And decryption:

unsigned char key = 0xAB;
QFile file("encrypted.mp3");
file.open(QIODevice::ReadOnly);
auto byteArray = file.readAll();
for(int i=1024;i<byteArray.length();i++){
     byteArray[i] = byteArray[i]^key;
}

QBuffer buffer(&byteArray);
buffer.open(QBuffer::ReadOnly);

// give the IO to the media player
QMediaPlayer player;
player.setMedia(QUrl(), &buffer);
player.play();

In the for-loop, I want to declare i as qint64 rather than int. But the compiler shows QByteArray::​operator[](int i).

Upvotes: 1

Related Questions