Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Highlighted
New Developer
Posts: 8
Registered: ‎05-15-2009
My Device: Not Specified

Audio Play/Record and Seek

[ Edited ]
Hi.

I am attempting to create an audio application that can play/record an audio (AMR) file stored locally on the device.  It needs to be able to seek to any position as well.  I have analyzed the BufferedPlayback example and can get simple audios to play by modifying the code to read from the SD card.  However, I am having difficulty understanding the read() method in the LimitedRateSourceStream class.  If I use the line _baseSharedStream.read(b,off,len), it takes the whole file and plays it.  I think I need to have control over the bytes the DataSource consumes...so I can stop, reposition, then play/record from that position.

Anyone have some sample code or reference that addresses this use-case?

Thanks
Chris
Message Edited by Chris_V on 05-22-2009 12:44 PM
Developer
Developer
Posts: 283
Registered: ‎07-22-2008
My Device: Not Specified

Re: Audio Play/Record and Seek

Since the file is local, you do not need to use a dataSource as in the playback example. Just create the player using a file URL.

You can still control the player by start/pause commands and you can seek to any position using the player.setMediaPosition().

So you have all the APIs to do what you want to do.

 

Now if you choose to use the example, you need to play on  _baseSharedStream.setCurrentPosition(pos);

You can set it in the Connect() if you are starting from an arbitray position, and also you can theoretically modify the current position inside the player read() method before the _baseSharedStream.read() is called.

 

But the difference between the two methods is that in the first one, you deal with time ( in microseconds) - So you call tell how long is the media and you can move in terms of time.

 

In the second method where you use a datasource, you seek using bytes. So you need to know the sampling rate to translate time to number of bytes.

 

Rab

New Developer
Posts: 8
Registered: ‎05-15-2009
My Device: Not Specified

Re: Audio Play/Record and Seek

Thanks Rab.

 

I was looking into the first option you mentioned using the setMediaPosition() method.  Then I noticed some posts about how it did not work on some devices or versions.  That is what made me look at the second option of DataSource and SourceStream.

As for the second option, I implemented the following inside the SourceStream of the DataSource class...

 

public int read(byte[] b, int off, int len) throws IOException
{
     return _baseSharedStream.read(b, off, len);
}

 

My Problem is that It reads the entire file in one read() call and plays until the end ignoring any seek() methods. 


This is the order of methods I call.

1-Player.start().
2-Sleep(3000).  Play for three seconds.
3-Player.stop().
4-DataSource.seek(0).  Hoping to reposition the audio at the beginning of the amr file.
5-Player.start().


If resumes playback at the third second instead of playing from the beginning.

I have been searching for examples, but have not been successful in finding any.  Any guidance would be appreciated.


Thanks again,
Chris V

Developer
Developer
Posts: 283
Registered: ‎07-22-2008
My Device: Not Specified

Re: Audio Play/Record and Seek

From my experience working with different devices, setMediaPosition() works fine. I found some problems using the simulator not the devices.

 

For the problem you are having, I would suggest to look at the seekType. In the dataSource there is a getSeekType() method, change it to return RANDOM_SEEKABLE instead of SEEK_TO_START. That can have an effect. Also check if you are returning the correct size of the file.

A third thing to test ( just for debugging) is to  modify the read() method to
public int read(byte[] b, int off, int len) throws IOException
{

     baseSharedStream.setCurrentPosition(xxx);
     return _baseSharedStream.read(b, off, len);
}

 

Just to test that the stream is seekable.

Usually the read() is called with len = 58000 at a time for mp4 media ( This is from my observation only, it is different for other types of media such as mp3)

 

Rab

 

 

New Developer
Posts: 8
Registered: ‎05-15-2009
My Device: Not Specified

Re: Audio Play/Record and Seek

Thanks Rab.

 

I have a player working fine with seek ability.  However, in the simulators, the Storm and Bold are the only ones that I can hear audio.  Running on 8300 Curve, 8800 simulators, I do not hear audio.  Sometimes a pop or a quick hiss.  I get no errors or exceptions.  I also see the read method being called asking for bytes.  The program flow runs well, just no sound on the 8300,8800 simulators.

 

Any ideas what is happening?

 

Thanks again,

Chris V

Developer
Developer
Posts: 283
Registered: ‎07-22-2008
My Device: Not Specified

Re: Audio Play/Record and Seek

I am assuming that you are using OS 4.2 for the 8800 and the 8300.

From my experience, the 4.2 simulators are not good at playing media ( audio/video). For example I was never able to run a video piece on those simulators.

Did you try it on the device?

I am sure that your code will run fine on the device itself.

 

Rab

New Developer
Posts: 8
Registered: ‎05-15-2009
My Device: Not Specified

Re: Audio Play/Record and Seek

[ Edited ]

Thanks for reply.

 

I am using 4.5 and 4.2.1 for the ones that don't work.  I forgot to mention that they do play audio if I just pass the file (AMR) directly to the Player instead of my custom DataSource.  I will test this on a real device soon.

 

Thanks,

Chris V

 

Message Edited by Chris_V on 06-11-2009 11:07 AM
New Member
Posts: 1
Registered: ‎02-03-2012
My Device: 9810
My Carrier: airtel

Re: Audio Play/Record and Seek

Hi , Thanx for your help ,it helped me to seek at desired position.

Just a little correction . It is RANDOM_ACCESSIBLE not RANDOM_SEEKABLE