4

I am developing a media player using vlc-qt , Actually I want a button which will play do the fast backward operation. I don't have the problem with the fast forward operation but not able to implement the fast backward operation, Is there any function there in vlc-qt which will play the video backwards. Here are the buttons code which I am using for fast forward and fast backward operation

void expPlayer::on_pushButton_2_clicked()
{
    m_player->setPlaybackRate(m_player->playbackRate()+1);
}

void expPlayer::on_pushButton_3_clicked()
{
    //It should play the video backward with more playback rate.
}

Here is my full code

#ifndef EXPPLAYER_H
#define EXPPLAYER_H

#include <QMainWindow>
#include "VLCQtCore/Instance.h"
#include "VLCQtCore/MediaPlayer.h"
#include "VLCQtCore/Media.h"
#include "VLCQtCore/Common.h"
#include "VLCQtCore/Config.h"
#include "QPushButton"
#include "QtMultimedia/QMediaPlaylist"
#include "VLCQtWidgets/WidgetVideo.h"
#include "VLCQtWidgets/WidgetSeekProgress.h"
#include "QSlider"
#include "QFileDialog"
#include "QInputDialog"
#include "QLabel"
#include "QListView"
#include "QBoxLayout"
#include "VLCQtWidgets/WidgetSeek.h"
QT_BEGIN_NAMESPACE
namespace Ui { class expPlayer; }
QT_END_NAMESPACE

class expPlayer : public QMainWindow
{
    Q_OBJECT

public:
    expPlayer(QWidget *parent = nullptr);
    ~expPlayer();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();
    
    void on_pushButton_3_clicked();
    
private:
    Ui::expPlayer *ui;

    VlcInstance *m_instance;
    VlcMedia *m_media;
    VlcMediaPlayer *m_player;
    VlcWidgetSeekProgress *m_progressBar;
};
#endif // EXPPLAYER_H

#include "expplayer.h"
#include "ui_expplayer.h"

expPlayer::expPlayer(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::expPlayer)
{
    ui->setupUi(this);
    m_instance = new VlcInstance(VlcCommon::args(), this);
    m_player = new VlcMediaPlayer(m_instance);

    m_player->setVideoWidget(ui->m_video);
    ui->m_video->setMediaPlayer(m_player);
    m_progressBar=new VlcWidgetSeekProgress(this);
    m_progressBar->setMediaPlayer(m_player);
    ui->m_video->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
    ui->m_video->show();

    m_media = new VlcMedia("http://www.youtube.com/watch?v=Btv7G0BV45g",m_instance);
    m_player->open(m_media);
    qDebug()<<"m_player->video():"<<m_player->video();
    m_player->play();

    m_progressBar->resize(ui->m_video->width(),30);
    m_progressBar->move(ui->m_video->x(),ui->m_video->y()+ui->m_video->height()+20);
    m_progressBar->show();

}

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


void expPlayer::on_pushButton_clicked()
{



}

void expPlayer::on_pushButton_2_clicked()
{
    m_player->setPlaybackRate(m_player->playbackRate()+1);
}

void expPlayer::on_pushButton_3_clicked()
{
    //It should play the video backward with more playback rate.
}
qt 
Vinay Kumar
  • 674
  • 2
  • 9
  • 21

3 Answers3

1

This is not really a solution for your problem, but rather a little info on why you might not find a satisfactory answer.

The reason this functionality is usually not supported lies in the very nature of video codecs themselves. It is no coincidence that basically no video player offers that option, I checked VLC Media Player, Media Player Classic, Windows Films & TV, and Windows Media Player, none of them support it. The only software I tried out that could do it is the DaVinci Resolve video editing software, and even there, the problem was obvious: forward playback was smooth, and backward was weirdly choppy (unless when playing low-resolution files, where it did work fine).

So what's the problem?

In most video codecs the video data consists of a few keyframes separated by lots of intermediate frames. These intermediate frames don't actually contain all the necessary data to render them on their own, they only contain little data which enables them to be calculated based on the previous frame. A great basic explanation of how this works can be found in this video. At this point, it should already be clear why reversing this process might be problematic.

To actually implement this, you basically have to first calculate all frames between two keyframes in "forward" mode, and then reverse their order. Because video decoding usually involves a lot of hardware acceleration, implementing something like this is not trivial at all. A "naive" approach would likely result in terrible performance.

Since it seems that vlc-qt doesn't support it I'd say your options depend on what you want to achieve.

  1. If you just want to play around a bit, you can try to implement the reversing yourself:

    Unfortunately, I cannot find vlc-qt documentation online at the moment (their site seems to be down?) so i checked what else QT has to offer. I have never worked with this myself, so take this with a grain of salt...

    There is a class called QVideoFrame that basically encapsulates the pixel data of a decoded video frame. Note that decoded video data occupies orders of magnitude more memory then the encoded file, so I'd suggest splitting the video up into smaller parts (unless the video files you want to play are very, very small), then loading all the frames of one of the parts into maybe a vector of QVideoFrame objects, then reversing that vector and playing back the resulting sequence of frames. Even if this works though, performance is likely to be terrible...

  2. Therefore, if you are more serious about your project, I'd suggest either looking for a library that supports such a feature or just doing what almost every other video player does, quickly jump back in small steps...

GWD
  • 3,081
  • 14
  • 30
  • Right. It seems to me the way to go is to seek backwards until you find the nearest keyframe, then go forwards and decode until you're done. And you should also cache these decoded frames so it's O(n) rather than O(n^2) – user464014 Dec 12 '20 at 03:06
  • 1
    I already know about the logic you discuss in your 2nd point, you can check my comment in previous answer. And yes this answer is not helpful to me as I am aware of this scenario already. But thanks for your time. – Vinay Kumar Dec 12 '20 at 04:52
1

VLC does not have this capability. As a workaround, you could try VLC with ffmpeg. I never used it, but:

  1. You can use ffmpeg to reverse a video, see this and Reverse video playback through ffmpeg, e.g.
  2. You can use ffmepg with VLC, see this, e.g.

So I guess you could accomplish what you need with this solution.

Other related sources, which I am not certain will help you

  1. You may try combining other open source alternatives with VLC, similarly as suggested above for ffmpeg.

    1.1. You may try using AviSynth with VLC.

    1.2. You may try using Avidemux with VLC. It used to be possible to reverse a video with it (see also this), but I am not sure it is possible nowadays. I am not sure it is possible to combine VLC with Avidemux either.

    1.3. Video players that have frame by frame playback feature

    1.4. Video player with backward frame by frame stepping for Linux, including the extension Previous Frame.

    1.5. Gstreamer

  2. How can I reverse a video clip?

  3. https://forum.videolan.org/viewtopic.php?t=139871

  4. https://forum.videohelp.com/threads/345380-video-player-that-can-step-forward-backwards-and-change-play-speed

Note: OpenShot is another open source software that can play backwards... would you dare trying to combine it with VLC?

  • Yup as I can see you have given so many reference, I will check them and will be happy if you can provide some working example with code @sancho.sReinstateMonicaCellio – Vinay Kumar Dec 14 '20 at 17:06
  • 1
    As said, I never used these combinations. I pointed out my first choice, as `ffmpeg` is mature and well supported, and there are links that show it should be workable. AFAICT, this puts you quite closer to your objective than where you were. Taking the further step to a working code is yet another piece of work... – sancho.s ReinstateMonicaCellio Dec 14 '20 at 23:26
  • ok sir i will try these things, your answer didn't solve my whole problem but it is the most helpful to find my solution so I am accepting this answer. – Vinay Kumar Dec 15 '20 at 06:40
-1

LibVLC does not support playing the video backwards.

You can change the position or time properties though.

mfkl
  • 1,914
  • 1
  • 11
  • 21
  • Changing time properties will only change the position of the video but I want the reverse of the video, Is there is any way where I can store all the video frames in ```QByteArray``` or in some other data structure and just loop through it from end end to start. – Vinay Kumar Nov 02 '20 at 17:14