Playing stream with QMediaPlayer app not responding - c++

I using visual studio 2019 qt5.12.3
I use ffmpeg.exe to stream my pc screen and show it inside my app.
Its playing the video stream but if my stream down or stop and ill try to
lets say i start ffmpeg.exe and i can see my screen in my app, then ill kill the ffmpeg.exe and try to delete or reload new url its will crush or stuck
delete QMediaPlayer;
or
QMediaPlayer->deleteLater();
and not even
QMediaPlayer->setMedia();
working if the stream stop
its will crush the app or nor respond.
this is my code to play the stream
void Stream::LoadStream() {
QUrl StreamUrl = QUrl("https://example.com:2083/live/stream.flv");
vWidget = new QVideoWidget(this);
vWidget->setObjectName("vWidget");
vPlayer = new QMediaPlayer(this, QMediaPlayer::StreamPlayback);
vPlayer->setObjectName("vPlayer");
vPlayer->setVideoOutput(vWidget);
vPlayer->setMedia(StreamUrl);
vPlayer->play();
vWidget->show();
}
void Stream::StopStream() {
vWidget->deleteLater();
//vPlayer->setPosition(0); //tried but not helped
vPlayer->stop();
vPlayer->deleteLater(); // this crush the app if StreamUrl stoped streaming ..
delete vPlayer; // this crush the app if StreamUrl stoped streaming ..
}
void Stream::ChangeUrl(QString Url) {
vPlayer->setMedia(QUrl(Url););
}
how i can delete or remove the player ?

Related

Qt : issue for displaying IP-CAMERA stream

I'm develop a Qt app for displaying my IP-CAMERA stream. It has code similar to this project :
https://github.com/cleitonbueno/qt-rtsp-test/tree/widgets
QVideoWidget *_vw1 = new QVideoWidget;
QMediaPlayer *_player1 = new QMediaPlayer;
QGridLayout *layout = new QGridLayout;
layout->addWidget(_vw1,0,0,1,1);
QWidget *win = new QWidget();
win->setLayout(layout);
setCentralWidget(win);
_player1->setVideoOutput(_vw1);
const QUrl url1 = QUrl("rtsp://184.72.239.149/vod/mp4:BigBuckBunny_115k.mov");
const QNetworkRequest requestRtsp1(url1);
_player1->setMedia(requestRtsp1);
_player1->play();
When i play Bigbuckbunny video, video's packet is coming and media player plays. But When i write ip camera's rtsp address in Qurl, Media player can't play this stream.
Capture made with Wireshark shows that the rtsp packets are received. But media player is seen black screen.
I'm using linux ubuntu 16.04 Gnome 3 (86_64 GNU/Linux)
QT 5.10.0
QT creator is 4.5
I remove ip camera's username and password. But I also tried with username and password (rtsp://192.168.1.1:554/live/stream1 && rtsp://username:password#192.168.1.1:554/live/stream1).
Can you please help me. I can't understand the root cause of this problem.

Qt QMediaPlayer - QThread::start: Failed to create thread

I develop an application which the user can play multiple sounds at the same time. For this I use QMediaPlayer in conjunction with a matrix to hold each sound separately. The code is simple, for each sound I use a code like this:
media = new QMediaPlayer();
media->setMedia(QUrl::fromLocalFile(QFileInfo("sound.mp3").absoluteFilePath()));
media->play();
Everything is ok. But around playing the sound 115-125 (simultaneous sounds), the new sounds emit signal error(QMediaPlayer::ResourceError) with error code: QMediaPlayer::ResourceError - A media resource couldn't be resolved. Before emit error signal, it print on output this message: DirectShowPlayerService::doPlay: Unresolved error code 0x80004005 ()
This is not a problem, because I delete those sounds as soon as I detect this error.
The problem appears right after a couple of QMediaPlayer::ResourceError.
If I create a new sound, an error message appear on output window: QThread::start: Failed to create thread.
This error appear just after creating a new QMediaPlayer instance:
qDebug() << "before media = new QMediaPlayer(); (FILE)";
media = new QMediaPlayer();
qDebug() << "after media = new QMediaPlayer(); (FILE)" << media->error
The output:
before media = new QMediaPlayer(); (FILE)
QThread::start: Failed to create thread
after media = new QMediaPlayer(); (FILE) QMediaPlayer::NoError
This last kind of QMediaPlayer instance emit no error. More than that, the state is QMediaPlayer::PlayingState. But if I try to delete it delete(media) or to set the media to a null QMediaContent media->setMedia(QMediaContent()) to make the player to discard all information relating to the current media source, the application freezes.
Those two opperations works fine on he others sounds.
If I don't delete this kind of QMediaPlayer, I end to have no room for sounds. Somehow QMediaPlayer has a limited number of instances and every QMediaPlayer that I cannot delete anymore fill this number and let no room for new instances of QMediaPlayer.
The question is: how I can avoid this issue? If I limit the number of simultaneous sounds, what is the correct number of QMediaPlayer instances? If I set a limit, this limit can be to high for other machines. Or how to properly detect this malformed QMediaPlayer and properly delete it?
Also, if I wait for first QMediaPlayer::ResourceError signal to limit the number of sounds, this is sometimes too late, because the error signal is emitted a bit later and sometimes the application already create a malformed QMediaPlayer that I cannot delete anymore and this prevent the process to close.

Display QProcess output in another window

I'm using the QT Creator on Ubuntu.
I have GUI with a mainwindow and another window called "progress".
Upon clicking a button the QProcess starts and executes an rsync command which copies a folder into a specific directory. I created a textbrowser which reads the output from the rsync command. Also clicking the button causes the "progress" window to pop up.
So far so so good, now my problem.
Instead of showing the rsync output in my mainwindow i want it to be in progress.
I've tried several methods to get the QProcess into the progress via connect but that doesn't seem to work.
mainwindow.cpp
void MainWindow::on_pushButton_clicked()
{
if (ui->checkBox->isChecked()
)
m_time ="-t";
QObject parent;
m_myProcess = new QProcess();
connect(m_myProcess, SIGNAL(readyReadStandardOutput()),this, SLOT(printOutput()));
QString program = "/usr/bin/rsync";
arguments << "-r" << m_time << "-v" <<"--progress" <<"-s"
<< m_dir
<< m_dir2;
m_myProcess->start(program, arguments);
}
progress.cpp
void Progress::printOutput()
{
ui->textBrowser->setPlainText(m_myProcess->readAllStandardOutput());
}
I know it's pretty messy iv'e tried alot of things and haven't cleaned the code yet also I'm pretty new to c++.
My goal was to send the QProcess (m_myProcess) to progress via connect but that didn't seem to work.
Can you send commands like readyReadAllStandardOutput via connect to other windows (I don't know the right term )?
Am I doing a mistake or is there just another way to get the output to my progress window ?
m_myProcess is a member of the class MainWindow and you haven't made it visible to the class Progress. That's why you have the compilation error
m_myProcess was not declared in this scope
What you could do:
Redirect standard error of m_myProcess to standard output, such that you also print what is sent to standard error (unless you want to do something else with it). Using
m_myProcess.setProcessChannelMode(QProcess::MergedChannels);
Make the process object available outside MainWindow
QProcess* MainWindow::getProcess()
{
return m_myProcess;
}
Read the process output line by line in Progress. It needs to be saved in a buffer because readAllStandardOutput() only return the data which has been written since the last read.
... // somewhere
connect(window->getProcess(), SIGNAL(readyReadStandardOutput()), this, SLOT(printOutput())
...
void Progress::printOutput(){
//bigbuffer is member
bigbuffer.append(myProcess->readAllStandardOutput();)
ui->textBrowser->setPlainText(bigbuffer);
}

QMediaRecorder does not record anything

I have a program that records video from a web camera. It shows the camera view in the form. When start button clicked it should start recording video and should be stopped after pressing stop button. Program compiles fine but no video is recorded. Can anyone say what is the wrong with it?
Here is my code.
{
camera = new QCamera(this);
viewFinder = new QCameraViewfinder(this);
camera->setViewfinder(viewFinder);
recorder = new QMediaRecorder(camera,this);
QBoxLayout *layout = new QVBoxLayout;
layout->addWidget(viewFinder);
ui->widget->setLayout(layout);
QVideoEncoderSettings settings = recorder->videoSettings();
settings.setResolution(640,480);
settings.setQuality(QMultimedia::VeryHighQuality);
settings.setFrameRate(30.0);
//settings.setCodec("video/mp4");
recorder->setVideoSettings(settings);
recorder->setContainerFormat("mp4");
camera->setCaptureMode(QCamera::CaptureVideo);
camera->start();
}
void usbrecorder::on_btn_Record_clicked()
{
usbrecorder::startRecording();
}
void usbrecorder::on_btn_Stop_clicked()
{
usbrecorder::stopRecording();
}
void usbrecorder::startRecording()
{
recorder->setOutputLocation(QUrl::fromLocalFile("C:\\Users\\Stranger\\Downloads\\Video\\vidoe_001.mp4"));
recorder->record();
}
void usbrecorder::stopRecording()
{
recorder->stop();
}
This is due to limitations on Windows.
As mentioned in Qt documentation here: https://doc.qt.io/qt-5/qtmultimedia-windows.html#limitations
Video recording is currently not supported. Additionally, the DirectShow plugin does not support any low-level video functionality such as monitoring video frames being played or recorded using QVideoProbe or related classes.
You need to specify an output location:
QMediaRecorder::setOutputLocation(const QUrl& location)
e.g.
setOutputLocation(QUrl("file:///home/user/vid.mp4"));
Try to print the state, status and error message:
qDebug()<<record.state();
qDebug()<<record.status();
qDebug()<<record.error();
and see what it prints. With those messages you can have a clear picture of your problem. Maybe QMediaRecorder cannot access your camera.

wxWidgets - wxMediaCtrl - video doesn't play

I want to create a simple video player with C++ and wxWidgets. I put wxMediaCtrl and wxFileDialog controls and created this code for button click event:
wxFileDialog * fopen = new wxFileDialog(this, wxT("Wybierz plik"), wxT(""), wxT(""), wxT("MP4 file (*.mp4)|*.mp4|AVI file (*.avi)|*.avi"));
if (fopen->ShowModal() == wxID_OK)
{
wxString fname = fopen->GetFilename();
media->Load(fname); // media is pointer to wxMediaCtrl object
media->Play();
}
delete fopen;
When I open file, it doesn't play. I have no idea what to do.
The documentation states:
For general operation, all you need to do is call Load() to load the file you want to render, catch the EVT_MEDIA_LOADED event, and then call Play() to show the video/audio of the media in that event.
So the problem looks to be that the file hasn't finished loading when you try to play it. You can also see the mediaplayer sample in the samples directory of your wxWidgets installation for more details.