Play/Pause/Stop MP3 audio file | (Visual) C++ - c++

I want to try and make an MP3 player for Windows. I searched for a function to play audio and found PlaySound() and mciSendString(), from my "research" I found that PlaySound() is only for .wav files, but, for now at least, I want .mp3. I tried mciSendString(), if in the play command, at the end of string I have the parameter "wait"(mciSendString("play audio.mp3 wait", NULL, 0, 0)) then the audio plays fine, but, I can't stop it, I will have to wait(what a surprise) for the audio to end, I found that the wait parameter does that(again, what a surprise). I tried then something like that:
while (!_kbhit()){ //as long as I don't press something
mciSendString("play audio.mp3", NULL, 0, 0); //without the wait
}
I thought that this function might have some sort of pointer that points to where exactly we are in the audio, how much of it we have heard, and with each execution of the command with the same audio, the pointer going, little by little, to the end, to the last "element" of the .mp3 file(note: I don't have the slightest idea how mp3 files and reading from them works)
I seached on the Internet for an example of proper use of mciSendString(), but I couldn't find any clear example/answer or something that works for me, for example, many were saying that still, without the wait it would work, but it didn't. So, here I am now.
What I'm asking: a clear example(code if possible) on how to use mciSendString or other function(s) to do the same thing.
Thank you for listening(reading actually) my problem.

Related

Why mciSendString cannot open my mp3 file?

I am trying to play MP3 audio in C++ Visual Studio 17.3.0, but keep getting MCIERROR 275 followed by 263.
My .mp3 file is in the same directory as my .cpp file.
My code goes something like this:
MCIERROR me = mciSendString(TEXT("open ""Music.mp3"" type mpegvideo alias mp3"), NULL, 0, NULL);
while(true){
me = mciSendString(TEXT("play mp3"), NULL, 0, NULL);
}
Have tried different .mp3 files, different directory, and different function for playing the sound (PlaySound()), which gave me a very similar result/error.
What could be the cause of my problem?
The first is to open:
mciSendString("open Summer.mp3 alias song",NULL,0,NULL)
Add the relative path or absolute path of the file after open (depending on the relative position of the music you play and your program)
We could understand alias as replacing your music name with the name after alias, which is convenient for us to carry out subsequent operations, only need to enter your alternative name (to save the trouble if the song name is long)
The last three parameters can be written as I do, because we are just simply playing music, so there is no need to go into details.
Next is to play:
mciSendString("play song repeat",NULL,0,NULL);
play+music name (or an alternative name after alias)+[play selection]
Playback options include repeat, wait.
repeat means to repeat the song.
wait means that the function does not return until the song has finished playing.

MoSync - Edit video

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!

Streaming MP3 from Internet with FMOD

I thought this would be a relatively simple task with something like FMOD, but I can't get it to work. Even the example code netstream doesn't seem to do the trick. No matter what mp3 I try to play with the netstream example program, I get this error:
FMOD error! (20) Couldn't perform seek operation. This is a limitation of the medium (ie netstreams) or the file format.
I don't really understand what this means. Isn't this exactly what the netstream example program was for? to stream some file from the internet?
I can't get passed the createSound method
result = system->createSound(argv[1], FMOD_HARDWARE | FMOD_2D | FMOD_CREATESTREAM | FMOD_NONBLOCKING, 0, &sound);
EDIT:
This is what I modified after reading Mathew's answer
FMOD_CREATESOUNDEXINFO soundExInfo;
memset(&soundExInfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
soundExInfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
soundExInfo.suggestedsoundtype = FMOD_SOUND_TYPE_MPEG;
result = system->createSound(argv[1], FMOD_HARDWARE | FMOD_2D | FMOD_CREATESTREAM | FMOD_NONBLOCKING | FMOD_IGNORETAGS, &soundExInfo, &sound);
I get two different errors depending on which files I use.
Test 1
URL: http://kylegobel.com/test.mp3
Test 1 Error: (25) Unsupported file or audio format.
Test 2 URL: http://kylegobel.com/bullet.mp3
Test 2 Error: (20) Couldn't perform seek operation. This is a limitation of the medium (ie netstreams) or the file format.
Before I made the change, I could use netstream to play "C:\test.mp3" which is the same file named test.mp3 on the web, but that no longer works with the above changes. Maybe these files are just in the wrong formats or something? Sorry for my lack of knowledge in this area, I really don't know much about sound, but trying to figure it out.
Thanks,
Kyle
It's possible the MP3 has a large amount of tags at the start, so FMOD reads them then tries to seek back to the start (which it can't do because it's a net stream). Can you try using FMOD_IGNORETAGS and perhaps FMOD_CREATESOUNDEXINFO with suggestedsoundtype set to FMOD_SOUND_TYPE_MPEG?
If that does't work could you post the url to a known not working MP3 stream?
EDIT:
The file in question has around 60KB of tag data, FMOD is happy to read over that stuff but for the MPEG codec to work it needs to do some small seeks. Since you cannot seek a netstream all the seeks must be contained inside the low level file buffer. If you tweak the file buffer size, make it a bit larger you can overcome this restriction. See System::setFileSystem "blockalign" parameter.

PlaySound() mmslib does not play existing sound

EDIT: Solved. Simply the .wav file was not accepted by Windows. I plucked one of Windows own files and renamed it to what my previous file was called and it plays without problem.
I don't know why this can't play the existing file. Windows gives a chime in that something is wrong but I have no clue what.
I added a check right before to make sure it exists. I have also tried absolute paths.
string wavPath = "c:\\frog.wav";
struct stat stFileInfo;
bool blnReturn = (stat(wavPath.c_str(), &stFileInfo) == 0); //this returns true
FILE* fp = fopen(wavPath.c_str(), "r");
if (fp) {
fclose(fp); //this triggers
}
PlaySound(wavPath.c_str(), NULL, SND_FILENAME | SND_ASYNC); //m_hinstance
//C:\\Users\\Wollan\\My Code\\A\\Debug\\frog.wav
//TEXT("frog.wav")
//TEXT(wavPath.c_str())
//(LPCSTR)"frog.wav¨
The file plays fine in WMP.
This following code perfectly works:
PlaySound(L"C:\\Windows\\Media\\Cityscape\\Windows Balloon.wav", 0, SND_FILENAME );
Adding SND_ASYNC fails to play.
The documentation says:
The pszSound parameter is a file name. If the file cannot be found,
the function plays the default sound unless the SND_NODEFAULT flag is
set.
And:
PlaySound searches the following directories for sound files: the
current directory; the Windows directory; the Windows system
directory; directories listed in the PATH environment variable; and
the list of directories mapped in a network. If the function cannot
find the specified sound and the SND_NODEFAULT flag is not specified,
PlaySound uses the default system event sound instead.
No other case is specified for this outcome.
Therefore, that you hear a chime indicates that the file is not being found, despite your assurances to the contrary.
I'd double-check the result of that stat call; I can't even find stat in the documentation; it doesn't appear to be part of Windows.
PlaySound(L"C:\Windows\Media\Cityscape\Windows Balloon.wav", 0, SND_FILENAME );
Adding SND_ASYNC fails to play.
This answer is right!
It is because the ASYNC mode plays the music after the function returns.
Your code may have exited before the music plays.
use int x, cin>>x, after PlaySound function, you will find that it works well.

Copy QuickTime audio to another QuickTime movie

I'm trying to copy a section of audio from one QuickTime movie to another one but without success; the audio doesn't seem to be copied.
C++ basic code:
// Copy from another QT movie, *src, to this one
soundTrack = NewMovieTrack(myMovie, 0, 0, kFullVolume);
soundMedia = NewTrackMedia(soundTrack, SoundMediaType,
GetMediaTimeScale(src->soundMedia), NULL, 0);
BeginMediaEdits(soundMedia);
InsertTrackSegment(src->soundTrack, soundTrack, 0,
GetMediaDuration(src->soundMedia), 0);
EndMediaEdits(soundMedia);
I don't want to transcode the sound, just copy the encoded sound frames across. I realise this basic code will copy all of the sound frames in the movie.
I am doing some other editing with the video file so I don't want to go through QTKit if I can possibly help it.
The code is good, I can get sound using it. I made some mistake in another part and ended up selecting the wrong source sequence for the sound. Sorry about that.