I know that this question is a duplicate. But in other questions, people advise Phonon which is not available in Qt 5+ (I'm using 5.4).
I also tried to use QAudioOutput:
QFile inputFile;
inputFile.setFileName("/home/efog/G6_Build/sound.wav");
inputFile.open(QIODevice::ReadOnly);
QAudioFormat format;
format.setSampleRate(44100);
format.setChannelCount(2);
format.setSampleSize(16);
format.setCodec("audio/wav");
QAudioOutput *audio = new QAudioOutput( format, 0);
audio->start(&inputFile);
But it is not working, same as QSound:
QSound::play("/home/efog/G6_Build/sound.wav");
NAS and GStreamer are installed. So, how can I play wav files?
Sometimes QSound takes some time to play when it first loads the file. Try creating a QSound object with the file, and playing it afterwards, and maybe give it a little time.
QSound *sound = new QSound("/home/efog/G6_Build/sound.wav");
sound->play();
And are you sure, your wav file is really a wav file? I've seen audio files with wav extension, but actually they were mp3 files. Maybe try with another audio file first.
Related
I am trying to use libav to convert an MP4 file to an MP3 file. Basically trying to achieve what ffmpeg -i filename.mp4 filename.mp3 does. I've found this official example. But when I run it with an input MP4 and an output MP3 I get an error:
Invalid audio stream. Exactly one MP3 audio stream is required.
I am not at all familiar with this library but I think I have narrowed the problem down to this line:
ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);
It seems to copy all streams for a video file but we only need one for the MP3 file? I am not sure. There doesn't seem to be a function to copy only the parameters relevant to audio. I checked the sources, avcodec_parameters_copy does a simple memcpy.
Questions:
Is this the actual problem?
How do I solve it?
Am I on the right track to achieve the goal of extracting audio from a video file? I've seen this question (and other similar questions like this and this) on here but none seem to have a complete code example. The C API documentation for this library is also a little lacking.
You can have multiple audio tracks in mp4 file, but only one such track in an mp3 file. The easiest fix for the remuxing example would be to replace lines 101-103:
if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO ||
stream_index != 0) {
This, naturally, is relevant only if the output is mp3.
PS, make sure that your input mp4 uses the MP3 audio codec. If it does not (and most have AAC or AC3 these days), it's not enough to remux the file, you also need to decode and re-encode the audio stream.
I have a encrypted file that packed many mp3 sound tracks, I want to decrypt it while my cocos2d-x game is running and play one specific mp3 as background music without any temp files are generated, but, the api in cocos2d-x can only Accept exsiting .mp3 file on disk, so how do I do to make cocos2d-x read mp3 data that I decrypted in memory?
If you are not playing from a filepath, you will have to edit the cocos2d-x audio engine source codes.
For example for iOS, the bgm is loaded through the -(void) load:(NSString*) filePath function of CDLongAudioSource in CDAudioManager.m
NSString *path = [CDUtilities fullPathFromRelativePath:audioSourceFilePath];
audioSourcePlayer = [(AVAudioPlayer*)[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
It is calling initWithContentsOfURL for the AVAudioPlayer object. You can either modify this or create a separate function that uses initWithData to suit your needs.
As for Android, it seems more complicated. I have traced it down to this createUrlAudioPlayer(const AudioPlayerProvider::AudioFileInfo &info) function in AudioPlayerProvider.cpp that is performing the loading from filepath.
EDIT:
Another suggestion is not to use their audio engine but write your own class that will implement native platform functions to play audio from data.
After making a small video recorder application and being able to play that video again. I would like to make the possibility to pick X seconds from the video and put that into a new .MP4 file (or overwrite the old one, that would be even better).
I am using the MoSync C++ Native UI and VideoViewer. I know I can get the position and that part is all fine, and according to the MoSync documentation.
char buf[BUFFER_SIZE];
maWidgetGetProperty(videoViewHandle,
MAW_VIDEO_VIEW_CURRENT_POSITION,
buf,
BUFFER_SIZE);
int seconds = 5;
//So here I need to make a new file ranging from buf to buf + seconds
However, I have absolutely no clue as to where to look for this. Should I use mp4 header files and create my own mp4 (how is this even done? and is this cross-compatible?).
Will appreciate any advice/help you can offer!
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
I tried to play .wav file in Qt by using QSound::play
I've tried this code:
QSound::play("airplane.wav");
No error when build but when run there is no sound?!
This rang a bell for me, so I found the code I use to handle sounds. Our platform is Windows, so this is what works for us. I wrapped all this up in a player class. My notes to myself said that QSound wants absolute paths, in platform format (found by examining the QSound code). So try getting the file path by something like this
// (note the "sSoundPath" variable is set to where we store our sound files).
static const QString sSoundPath("./resources/sounds/");
elsewhere...
// QSound wants absolute paths, in platform format
QFileInfo fileInfo(soundFile);
if (fileInfo.isRelative())
{
// we assume one of our own sound files in a relative path
fileInfo.setFile(sSoundPath + soundFile);
fileInfo.makeAbsolute();
}
if (!fileInfo.exists())
{
return false;
}
mSoundFile = QDir::toNativeSeparators(fileInfo.filePath());
Now you can go ahead and try to play the sound file.
I have spent countless days on a similar issue. Basically, I found out that QSound does not support wave files with 44100 Hz sample rate. Check out my discovery at QT5 QSound does not play all wave files
A side note, QSound does not support QT resources, in case you are using one. A workaround is to copy the resource into a file, and then play that file with QSound from the hard drive. Hopefully this info helps.