I'm connecting the QMediaPlayer::error() signal and trying to play a video file:
QMediaPlayer *player = new QMediaPlayer;
QMediaPlaylist *playlist = new QMediaPlaylist(player);
playlist->addMedia(QUrl::fromLocalFile("/path/to/file.mp4"));
QVideoWidget *videoWidget = new QVideoWidget;
player->setVideoOutput(videoWidget);
videoWidget->resize(640, 340);
videoWidget->show();
ErrorPrinter *errorPrinter = new ErrorPrinter(player);
QObject::connect(player, SIGNAL(error(QMediaPlayer::Error)), errorPrinter, SLOT(printError(QMediaPlayer::Error)));
player->play();
The video widget shows, but nothing is playing, so it must have failed somewhere. However, the QMediaPlayer::error() signal is never emitted! The Application Output is empty, there are no asserts, the play() function is void (no return value to indicate success or failure), and playlist->addMedia always returns true.
How am I supposed to find out what went wrong?
The QMediaPlaylist(player) construction only sets a QObject parent. It doesn't link the playlist to player - the player is unaware of the playlist.
So, you've never set the playlist on the player. You may also need to set the playlist index - to 1 or perhaps zero (? - the docs are not clear on that).
playlist->setCurrentIndex(1);
player->setPlayList(playlist);
player->play();
Related
I want to play background music continually in a loop until the game ends.
in the header file:
QMediaPlayer * music = new QMediaPlayer();
in the cpp file:
startGame(){
music->setMedia(QUrl("qrc:/sounds/backgroundmusic.mp3"));
music->play(); }
stopGame(){
music->stop(); }
Right now my music plays thru to the end but does not restart. How can I get it to loop over again again?
Is there a QMediaPlayer member I can use, or should I run it in a while loop, or what?
Sounds like what you want is QMediaPlaylist. QMediaPlaylist allows you to control the playback mode, and in this case you would use Loop. This approach has other advantages too, such as CurrentItemInLoop. CurrentItemInLoop will play the current playlist item in a loop, meaning that if you add more songs in the future you can select a song then loop only that track. Thus, you only need a single playlist for most needs. Below is some example code, I do not currently have a means to test it though (No Qt multimedia extensions installed on this machine). Should demonstrate the point reasonably well though.
QMediaPlaylist *playlist = new QMediaPlaylist();
playlist->addMedia(QUrl("qrc:/sounds/backgroundmusic.mp3"));
playlist->setPlaybackMode(QMediaPlaylist::Loop);
QMediaPlayer *music = new QMediaPlayer();
music->setPlaylist(playlist);
music->play();
I need to draw an oscillogram of audio track. The audio could be stored with video too. I play audio with such code:
QMediaPlayer* player = new QMediaPlayer;
//connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
player->setMedia(QUrl::fromLocalFile("/home/mikhail/Downloads/BRAT.mkv"));
player->play();
I need to play any of audio tracks in video file and display it's oscillogram.
How can I realize it?
I've found an example in Qt examples: http://doc.qt.io/qt-5/qtcharts-audio-example.html . That's what I need but the sound streams from micro. I'm new at Qt, although an example is simple, I can't understand how to replace data from micro with data from player.
I can guess that I need to replace QAudioInput:
QAudioFormat formatAudio;
formatAudio.setSampleRate(8000);
formatAudio.setChannelCount(1);
formatAudio.setSampleSize(8);
formatAudio.setCodec("audio/pcm");
formatAudio.setByteOrder(QAudioFormat::LittleEndian);
formatAudio.setSampleType(QAudioFormat::UnSignedInt);
QAudioDeviceInfo inputDevices = QAudioDeviceInfo::defaultInputDevice();
m_audioInput = new QAudioInput(inputDevices,formatAudio, this);
m_device = new XYSeriesIODevice(m_series, this);
m_device->open(QIODevice::WriteOnly);
m_audioInput->start(m_device);
But I can't find how to give to QAudioInput a buffer of raw data from QMediaPlayer.
Also I have working code to get raw data with ffmpeg, but I think it could be done with QMediaPlayer and it would be easier.
Thanks for any help!
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.
I try to play mp3 files declared in the resource, but it show:
Btn clicked
current media: "qrc://sound/sound/FarAway.mp3"
Error : QMediaPlayer::FormatError
Media state : QMediaPlayer::InvalidMedia
Here's how I set media:
player = new QMediaPlayer(this);
player->setMedia(QUrl(mediaFilePath));
qDebug() << "current media: " << player->currentMedia().canonicalUrl().toString();
connect(player, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(handleStateChanged(QMediaPlayer::State)));
connect(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), SLOT(handleMediaStateChanged(QMediaPlayer::MediaStatus)));
connect(player, SIGNAL(error(QMediaPlayer::Error)), SLOT(handleError(QMediaPlayer::Error)));
According to this post it said QMediaPlayer need to be called play() after the callback of mediaStatusChanged(), which is what I've done exactly. So what's the problem???
P.S. I could play the mp3 file from the QMediaPlayer Example as local file.
UPDATE 1: I can play the mp3 file as local file...
Your problem is now no longer a problem, you can play a Qt resource in the QMediaPlayer. Answer found here, and I'm confirming it here in case people are looking.
This code works for me when testing in my local project.
player->setMedia(QUrl("qrc:/audio/audio/Revival_Song01.mp3"));
You should play a file from disk; not a Qt resource. Since the resources are not supported yet. You can copy the file from resource to your hard drive on the fly and then play it :
QFile::copy(":/files/FarAway.mp3" , "/some/path/FarAway.mp3");
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.