Playing mp4 video using Phonon - c++

I'm trying to write a very simple video player using QT and Phonon, on Windows. My backend is phonon_ds94. First of all, here is the code when I click on "Play" :
if (!this->_files.empty()) {
QString file = this->_files.front();
this->_files.pop();
Phonon::MediaSource _src(file);
this->ui.videoPlayer->play(_src);
}
(Here, file is a std::queue of files to read)
If I want to play a .avi ou .wmv, everything works fine. My video play, it's perfect.
But when I want to play a .mp4 file, nothing happen. The videoPlayer stay black.
I've search on the web and see that there is a BackendCapabilities::availableMimeTypes, so I've try it to be sure that my backend is compatible with mp4 - it's in the list. Here is the list of available mime types:
application/vnd.ms-wpl application/x-mplayer2 application/x-ms-wmd
application/x-ms-wmz audio/3gpp audio/3gpp2 audio/aiff audio/basic
audio/mid audio/midi audio/mp3 audio/mp4 audio/mpeg audio/mpegurl
audio/mpg audio/vnd.dlna.adts audio/wav audio/x-aiff audio/x-mid
audio/x-midi audio/x-mp3 audio/x-mpeg audio/x-mpegurl audio/x-mpg
audio/x-ms-wax audio/x-ms-wma audio/x-wav midi/mid unknown video/3gpp
video/3gpp2 video/avi video/mp4 video/mpeg video/mpg video/msvideo
video/quicktime video/vnd.dlna.mpeg-tts video/x-mpeg video/x-mpeg2a
video/x-ms-asf video/x-ms-asf-plugin video/x-ms-wm video/x-ms-wmv
video/x-ms-wmx video/x-ms-wvx video/x-msvideo vnd.ms.wmhtml
I've also connected the stateChanged signal of the mediaObject to a slot, and when I try to read my video, there is an error saying that file format is not supported.
How can I have Phonon to support it? Should I install a codec pack, even if mp4 is in my list?

I recently had a similar problem and after trying a number of codec packs, here is the one that worked.
K Lite Mega Codec Pack
If you go into the advanced install, you can uncheck the "Tools", "Program" (Windows Media Player Classic), "Shell Extension", and later uncheck the free browser toolbars that come with it, you end up with just the codecs.
Afterwards I have been able to play anything on Windows using the qmediaplayer example program included in the Demos folder of the QtSDK.

Related

Add TOC chapters to MP4 with GStreamer 1.18 (VS2015)

How can I add chapters to MP4 files with GStreamer 1.18?
I have a Visual Studio 2015 C++ project that writes a video (H264) and audio (aac) stream to the disk using mp4mux. Now I would like to add chapters to the MP4 file that are compatible with regular video players like VLC.
I have tried to follow the documentation to create a GstToc and a dummy GstTocEntry, but it doesn't appear to be written to the file:
GstToc* toc = gst_toc_new(GstTocScope::GST_TOC_SCOPE_CURRENT);
GstTocEntry* new_entry = gst_toc_entry_new(GstTocEntryType::GST_TOC_ENTRY_TYPE_CHAPTER, "some_uid");
gst_toc_entry_set_start_stop_times(new_entry, 0, 50);
gst_toc_append_entry(toc, new_entry);
I then also tried to generate a new toc event and pass it to the video GstElement vin:
gboolean result = gst_element_send_event(vin, gst_event_new_toc(toc, true));
Did I miss anything in order to map the GstToc to the video stream? Do I need to tell mp4mux to process the toc? Or is this not supported?
GStreamer documentation seems to imply, that there is GstToc support in mp4mux:
Below hollow bullet point o indicate no support and filled bullets ***
indicate that this feature is handled.
MP4: * elst
The elst atom contains a list of edits. Each edit consists of (length, start, play-back speed).
I didn't find much on the elst atom or what an edit is. I tried using GST_TOC_ENTRY_TYPE_EDITION instead of GST_TOC_ENTRY_TYPE_CHAPTER, but that didn't change anything.
This page mentions "preliminary code in MP4 supporting chapters" in GStreamer.
I have seen ways to inject metadata files into existing mp4 files with ffmpeg and other tools which are not available on our system unfortunately. I could try to inject the chapters into the mp4 file header manually, but I'd very much like to avoid this post-processing step for obvious reasons. Any help would be greatly appreciated!

How do I know the format of audio file?

I want to make a music player and I want to filter out files not audio file on opening.
Should I use QAudioDecoder?
But every file I checked with QAudioDecoder tells me the same codec "audio/pcm".
QAudioDecoder decoder;
decoder.setSourceFilename(fileUrl.toLocalFile());
qDebug() << decoder.audioFormat().codec();
How do I know if the audio file's format is supported by Qt media player by not just checking if the file's name ends with ".mp3" or ".wav"?
And I found that some files' duration incorrect when playing on my music player.
But when I play the file with other music player apps, it gives correct duration on other music players.
Or my app can't play some files but others can.
the console says :
DirectShowPlayerService::doSetUrlSource: Unresolved error code
0x80070002 (?t?Χ??????w?????C)
but after I change the file name, it can be opened.
How should I fix those on my music player instead of fixing the files' probably wrong or unsupported formats one by one?
I wrote this code to check if the file I opened is a supported audio file.
QMediaPlayer audioChecker;
audioChecker.setMedia(fileUrl);
qDebug() << audioChecker.media().canonicalUrl().fileName();
qDebug() << audioChecker.isAudioAvailable();
if(audioChecker.error() == QMediaPlayer::NoError) {
qDebug() << "no error";
}
if(audioChecker.error() == QMediaPlayer::FormatError) {
qDebug() << "format error";
}
and it tells me no error no matter what file I tested.
console:
"musicplayer.exe"
false
no error
"musicplayer.exe"
false
no error
"musicplayer.ilk"
false
no error
"musicplayer.exe"
false
no error
"a song.mp3"
false
no error
But how can files not audio file get no error?
Why do audio file's audio not available?
Never mind. I just read that setMedia() return immediately and doesn't wait for the media to be loaded. so it's normal it gets no audio and no error because it's not loaded.
I guess I'll make a thread class to check my file.
By the way, incorrect duration of the file is fixed somehow. Does it relate to LAV Splitter?
From Qt's documentation:
For playing media or audio files that are not simple, uncompressed audio, you can use the QMediaPlayer C++ class […] The compressed audio formats supported does depend on the operating system environment, and also what media plugins the user may have installed.
A simple example of how to use the QMediaPlayer class:
player = new QMediaPlayer;
// ...
player->setMedia(QUrl::fromLocalFile("/Users/me/Music/coolsong.mp3"));
player->setVolume(50);
player->play();
To verify that the codec is supported, you can use the error() method of the QMediaPlayer class which will return you an error code (see the documentation).
So, after calling setMedia(), you can do something like:
if (player->error() == QMediaPlayer::FormatError)
{
// Codec/format unsupported
}
About the error code you get when opening files:
check that you have no \ characters in your path (if you have some, escape them with another \)
check if you have spaces, special characters, etc.
About how to check audio format in file without check its suffix, there's a tool names mediainfo, with the command line tool run as below:
mediainfo -f [filepath]
You'll get the full information about the file, both video and audio if they exists. And among these parameters, there's a "format" value under "Audio" category, that indicates the actual audio format inside. eg. AAC/AC3
About the file can be played after name changed, I consider maybe there are some space characters in the filename, or the Player just can't access the file specified by name.

Opencv VideoCapture, not opening some video files

I'm trying to use the opencv librarie to display video files to the screen using sdl-2. I got it to work with smaller files(20.5Mb), but when i tryed using bigger files (100 and 136Mb) it didnt work and i go the message "ERROR: Coudnt load the video < video.avi>".
cv::VideoCapture video;
video.open(videoName);
if (!video.isOpened())
{
SDL_Log("ERROR: Coudnt load the video <%s>", videoName.c_str());
return;
}
I don't know if size was the problem, but that would make the most sense to me. I've not found any documentation on size restrictions thought. Any ideas on how to fix it?
PS: All were .avi files, and the file's name was not the problem. Was able to open them with ffplay if that matters at all. OpenCV version 2.4.8

QMediaplayer streaming from a custom QIODevice with encryption on Mac OS (10.9)

i'm currently porting an application from Qt4(.8.4) to Qt5(.2.0).
I'm nearly done with all the known changes like deprecated toAscii()-function, missing QtGui and so on. Now we had a music player using the phonon framework which is not supported any more and got replaced by the QtMultimedia module including the QMediaPlayer and a bunch of Audio-Handling classes.
Our implementation of the player takes a custom QIODevice. This device provides an interface to encrypted audiofiles on the disk. Now the player asks the device for x bytes, the device reads from the encrypted file, decrypts the bytes the player asked for and returns them.
Now I searched for a function in the multimedia-module to reuse my IODevice and found the following function:
void setMedia(const QMediaContent & media, QIODevice * stream = 0)
and used it as follows:
m_pDecryptingMediaDevice = new BYIODevice(filename);
m_pDecryptingMediaDevice->open(QIODevice::ReadOnly);
m_pPlayer->setMedia(0, m_pDecryptingMediaDevice);
where m_pDecryptingMediaDevice is the QIODevice-subclass and m_pPlayer the QMediaPlayer.
Now on Windows everything works as expected. The QMediaplayer changes its MediaStatus to QMediaPlayer::LoadingMedia and asks my device for bytes. Then changes to the QMediaPlayer::State PlayingState and the status is set to BufferedMedia.
Everythings fine.
Unfortunalety on Mac OS (10.9.1) I only get QMediaPlayer::PlayingState and nothing more. The player/audiobackend never asks my device for bytes and doesn't call any other function.
I don't think that the mistake is concerned to the custom QIODevice but in the way it is given to the QMediaPlayer because the player doesn't even ask for any bytes or calls any function on the device.
I just tried to break it down to a little testproject:
QMediaPlayer *player = new QMediaPlayer(this);
QFile *music = new QFile("C:/Users/.../Music/Test.mp3");
music->open(QIODevice::ReadOnly);
player->setMedia(0, music);
connect(ui->pushButton, SIGNAL(clicked()), player, SLOT(play()));
connect(player, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(stateChanged(QMediaPlayer::State)));
Curiously this does not play at all - not on windows, not on Mac OS.
What always works is giving an URL to the player like
Has someone any experience in a similar case according to streaming out of an QIODevice to QMediaPlayer using the function setMedia(const QMediaContent & media, QIODevice * stream = 0)? I am stuck with this.
Best regards and many thanks in advance.
Jan
Just came to this page. There the available/chosen audio-backends for each platform are listed:
As you can see the DirectShow-Plugin (Windows) does support stream sources whereas AVM Foundation/Quicktime 7 (OSX) don't have streaming support. So I guess the only solution seems to ship a custom backend with the application (gstreamer, vlc).
Anyway,try give empty QMediaContent() to setMedia instead of 0. It is working OK for me (but,I try it in linux)
In your small test project,you use mp3 -- I'm not sure if it's supported.

QT phonon playback is failing when a QFILE is used for mediaSource, works fine when a string is passed

Below is the code I am using to play a video
QFile* file =new QFile(“C:\\Video\\test.avi”);
media->setCurrentSource(Phonon::MediaSource(file));
media->play();
Using this code the playback fails -what I see is the play bar at the bottom but the video never starts.
If I change the code to the following everything works as expected
media->setCurrentSource(Phonon::MediaSource(“C:\\Video\\test.avi”));
media->play();
Are there additional initialization steps required when using an iodevice? Ultimately my code will be using a custom iodevice which is not working as well.
This is an old post, but I wanted to clear up any confusion out in case it will help someone in the future.
QT does allow you to pass Phonon::MediaSource() a QIODevice. We successfully deployed our solution by creating our own subclass of QIODevice.
The reason it was not working for me was QT was having an issue with the codec I was using. When you use the QIO device you don't get the same format support as you would if you pass a string.
One other thing to note, while this solution works great on windows. On a mac when using the QIO device the entire file will be loaded into memory before it plays. In my case this was a deal breaker. Having an encrypted file is usless if the first thing you do is de-crypt the entire file and load it into memory.
From the Phonon::MediaSource documentation:
Warning: On Windows, we only support QIODevices containing the avi,
mp3, or mpg formats. Use the constructor that takes a file name to
open files (the Qt backend does not use a QFile internally).
I think that the last line should answer your question. Instead of a QFile, you can use a QString, or call the function QFile::fileName like this:
QFile* file =new QFile(“C:\\Video\\test.avi”);
media->setCurrentSource(Phonon::MediaSource(file->fileName()));
media->play();
If you take a careful look in the [Phonon Module docu][1], you will see that MediaSource cannot be constructed with QFile*.
By the way I don't see in your code any phonon paths. At least you should create audio sink and connect it with the mediaobject:
Phonon::AudioOutput *audioOut = new PhononAudioOutpu(Phonon::MusicCategory);//or the category you need
Phonon::createPath(mediaObject, audioOutput);
mediaObject->play();
Works fine with QFile