Im trying to get the duration of a Music, in libgdx
Im not talking about :
getPosition();
What I want is the Duration of the music. (in seconds)
Thanks
To be clear by "duration" you mean the total time the music would play without looping.
I don't think the Libgdx sound APIs expose this (the lowest common denominator sound API across desktop, Android and Web is pretty low ...).
You may be able to get this information out of the files you're loading into system, though (e.g., if they're wav or mp3 files there should be APIs to query their duration).
Its an old question but I will give my answer for the future visitors
To get the duration of a music file you can use the gdx-audio extension.
FileHandle file=Gdx.files.internal(filepath);
FileHandle external=Gdx.files.external("mygame/"+filepath);
if(!external.exists())file.copyTo(external); //copy the file to the external storage
Mpg123Decoder decoder = new Mpg123Decoder(external);
System.out.println("name:"+filepath+" duration:"+decoder.getLength());
if ur looking to stop the music when u want then by using
music.stop();
or pause the music by
music.pause();
or for other tasks refer to this link https://github.com/libgdx/libgdx/wiki/Streaming-music
Related
I'm creating an app in which multiple devices can connect to each other in a LAN and play songs from each other's device.
Right now, when device A requests a song from device B, B sends the song file back to A over a socket. Once the song finishes downloading, A starts playing it using MediaPlayer.
Now the problem with this is that even on a high speed LAN, it can take a couple of seconds to finish fetching the song, so there's a noticeable delay between selecting a song and it's playback actually starting.
I want to find a way to play a song while it's still being downloaded. Here are some possible solutions I found, but wasn't able to explore for certain reasons:
In the MediaPlayer documentation, I noticed a constructor that takes a MediaDataSource implementation allowing me to manually return parts of the media file whenever the MediaPlayer requires it so I could hold off returning a byte until it finishes downloading (if it hasn't finished downloading already), effectively acting like a "buffering" action. It seemed like a solution but unfortunately, my app's minSdk is set to 16 and MediaDataSource is for 23 and above only, so I couldn't try it out.
One option was to use MediaPlayer's setDataSource(FileDescriptor fd, long offset, long length) method. This would allow me to tell the MediaPlayer to only play up to a certain byte of the song. That way, I could wait for more parts of the file (or the entire file) to become available, and then use setNextMediaPlayer() and pass in a new MediaPlayer object that prepares the entire song and is made to seek up to the point where the previous media player object will stop playing so that there's a seamless transition.
But there's another problem with this. I need to be able to calculate the millisecond position that would be reached at that last specified byte of the first incomplete media player object. Otherwise I wouldn't know what position to seek the next media player object to in order to get a seamless transition. This calculation seems impossible for lossy formats.
I don't really know if this option will work or not, I'm just making assumptions. I noticed that setDataSource() takes a Uri. If that Uri points to a file on the phone, the media player just loads the entire file. But if the Uri points to an audio file on the internet that needs to be streamed, it figures that out on it's own and it handles all the details of downloading and buffering. So what I want to know is, is it possible to expose the song on device B as a Uri to device A so that media player just treats it as if it's a song on the internet? All this time I was using sockets and manually copying a file from one device to another so I have no idea how this would work. Could anyone explain if this is possible?
There's actually a reason why I haven't been exploring ways to "stream" a song from one device to another. That's because I want to song to be cached on device B so that later if I switch to another song and then back the previously played song from device A, it shouldn't have to stream it again. It should just play the cached copy.
Finally, I came across ExoPlayer. It seems to provide a large amount of customization. It seems like I could make custom implementations of it's classes to handle all the buffering. But the documentation and examples are few and far too complicated for me. I have no idea how to pull it off. Is this solution too complex for what I want to achieve?
Hope someone can point me in the right direction here.
Ended up using an answer from here:
MediaPlayer stutters at start of mp3 playback
This solution sets up a local server that the MediaPlayer can use to stream the file. The server only sends bytes to the MediaPlayer while those bytes are available. Otherwise, it blocks until more bytes are available. Thus the MediaPlayer buffers it as if it were a file from a web server.
I took the same class provided in that answer and just tweaked it to fit my situation.
is there anyway to play a file that is being dynamically added to, using android media player ?
I tried using RandomAccessFile :
public static RandomAccessFile tempMp3;
tempMp3 = new RandomAccessFile(Environment.getExternalStorageDirectory()+"/ggg", "rw");
StaticData.tempMp3.setLength(file_size);
StaticData.tempMp3.seek(0);
//Here I call the auto update function and after X bytes are written I call playMediaPlayer
StaticData.mediaPlayer.setDataSource(StaticData.tempMp3.getFD());
StaticData.mediaPlayer.prepare();
StaticData.mediaPlayer.start();
So basically I am updating and playing at the same time.
The problem is that MediaPlayer and my Update function both are accessing and moving the file pointer, which messes up the MediaPlayer.
Is there any workaround ?
Can I use separate file pointers ?
Solved this.
Java NIO to the rescue.
Using memory-mapped IO, we can write to our file, without disturbing the file pointer, so the android media player is happy. Here is a helpful link.
The trick is to set the size of our MappedByteBuffer = size of music file.
We also need to ensure that the media player pauses if we have not yet written to the buffer. This can be achieved by monitoring the file-pointer.
Suppose I have a sound file that I wish to play in this manner:
Start from the 0:00 mark.
When the sound file ends, replay from the 0:30.00 mark.
Essentially, I wish for the song to play from 0:00 to 0:30, then loop from 0:30 to the end.
How do you do this?
Usually, when playing Audio Files, I use AudioClip.
AudioClip audio = Applet.newAudioClip( this.getClass().getResource( "..." ) );
audio.loop();
It's because of bad experiences with loading the audio file when the project is packed into a .jar file. If the method you recommend uses another class, I would still be more than happy to listen. However, if you've encountered the same problem as I have and know how to fix it, please do tell me.
You might use a Clip for this, or if the clip is too large, feed the bytes directly to a SourceDataLine.
YouTubeQuery(..) take too long to show published video. Approximately 24h after upload video. Anyway to speed up this?
The amount of time that passed in between when a video is uploaded to YouTube and when it shows up in the YouTube search index can vary. We can't make any guarantees about that.
In general, one common practice that can lead to delays in indexing which you can avoid is uploading the video as unlisted/private and then later flipping it to public when you want the video to be "published". I'm not sure if you're doing that or not, but if you are, try uploading it as public initially instead.
If any of my fellow Xuggler users can tell me what I'm doing wrong, that would be awesome! I am doing the following:
Reading from ogv (ogg video)
Queueing the audio and video
Writing back to ogv
sounds simple right? The problem I am experiencing in my QueueMixer class is that the output file plays the audio 2x too fast, and no matter what I check or change with regards to pts it doesnt improve.
The eclipse project and all files being used are at this link:
http://dl.dropbox.com/u/7316897/paul-xuggled.zip
To run a test, compile and execute the StreamManager class; a test ogv file is included. Before anyone asks, yes I have to queue the data as it will be mixed with other data in a future version.
Audio has a sample rate. Make sure that you copy the sample rate from the input to the output, otherwise the system might use a default (like 44KHz while the original data was sampled at 22KHz which would create such an effect).
The fix is to multiply the sample count by two when extracting them from the ShortBuffer.
samples = new short[(int) audioSamples.getNumSamples() * 2];
audioSamples.getByteBuffer().asShortBuffer().get(samples);
Having half the samples causes the audio to play twice as fast.