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
Developer
rihan007
Posts: 455
Registered: ‎01-14-2009
My Device: Apple iPhone 3GS 16GB
Accepted Solution

End Of Media Fired Too Soon in OS 5

Hello Friends,

 

I have got an AMR player. which can seek to any duration and play from there. I have a PrivateInputStream Class inherited from the InputStream class which is used to seek in the AMR file . When i try to play the AMR file the End of Media event is fired as soon as the player is started. The file is aobut 12 seconds.

 

I dont have an issue when i get the inputstream directly and play. I have the issue when i get the inputstream from PrivateInputStream (to seek);

 

Please help guys

Developer
rihan007
Posts: 455
Registered: ‎01-14-2009
My Device: Apple iPhone 3GS 16GB

Re: End Of Media Fired Too Soon in OS 5

THis is what i am getting in the debug window if this helps.

 

Event:....................com.rim.playableStreams
MP: h=50331648,s=LD: +play
MN: play0(50331648) is audio, NO check for active pause
MN: play0(50331648)=0
MP: h=50331648,s=LD: -> PL
MP: h=50331648,s=PL: -play
Event:....................com.rim.mediaLoaded
Event:....................started
started
MP: h=50331648,s=PL: volChange 70
JVM: bklt @1494195: timer
JVM: bklt[1] @1494195: idle 3
JVM: bklt @1494195: setTimer 12
MP: h=50331648,s=PL: mStat: 0
Event:....................com.rim.timeUpdate
SMP[-989435546,MP: h=50331648]: BUFFERING = 33
SMP[-989435546,MP: h=50331648]: BUFFERING = 33
MP: h=50331648,s=PL: +sNMD
MN: signifyNoMoreData0(50331648)=0
MP: h=50331648,s=PL: -sNMD
MP: h=50331648,s=PL: mStat: -1
MP: h=50331648,s=PL: -> LD
MP: h=50331648,s=LD: +unld
MP: h=50331648,s=LD: -> UG
MN: unload0(50331648)=0 pauseHandle=0
MN: unload 1
MN: MEDIA_STOPPED received
MN: handle=50331648 staticsHandle=0
MP: h=50331648,s=UG: +mStp
MP: h=50331648,s=UG: +unlC
MN: finalize0(50331648)
MP: h=50331648,s=UG: -> UD
MP: h=50331648,s=UD: -unlC
MP: h=50331648,s=UD: -mStp
MP: h=50331648,s=UD: +unlC
MP: h=50331648,s=UD: -> UD
MP: h=50331648,s=UD: -unlC
MP: h=50331648,s=UD: -unld
AR: remove source 13
AR: setAudioMode 32
Event:....................endOfMedia        // this event is fired too soon ,even before the file startts playing

Developer
Posts: 1,474
Registered: ‎04-14-2009
My Device: Not Specified

Re: End Of Media Fired Too Soon in OS 5

Which version of Manager.createPlayer are you using: the one with InputStream or the one with DataSource? I don't know whether the InputStream one supports seeking, but the DataSource one should do just fine.

 

If you're using the InputStream Manager.createPlayer, then I suggest you log with what parameters your InputStream's methods (inluding skip()) are called and what they return. May be there's a bug in your implementation (I would imaging the InputStream-based player would try to skip/read+throw away some number of bytes in order to seek to a time index).

 

If you're using a DataSource+SourceStream Manager.createPlayer, I would also suggest you log all method invocation parameters and return values and then post them here. May be we can spot a bug.

Developer
Posts: 1,474
Registered: ‎04-14-2009
My Device: Not Specified

Re: End Of Media Fired Too Soon in OS 5

P.S. Are you providing the 6-byte AMR-NB header at the beginning of the stream before you start providing any AMR frames?

Developer
rihan007
Posts: 455
Registered: ‎01-14-2009
My Device: Apple iPhone 3GS 16GB

Re: End Of Media Fired Too Soon in OS 5

 

 

 

Hi klyubin,

 

I am using Manager.createPlayer with inputstream. I have a privateAMRInputStream which supports seeking. It has been working well in earlier OS like 4.5,4.6,4.7 etc. Its got issue only in OS 5

 

 


klyubin wrote:

P.S. Are you providing the 6-byte AMR-NB header at the beginning of the stream before you start providing any AMR frames?


 

Yes i am providing the AMR header . IT works fine in pervious OS versions

 

Developer
Posts: 1,474
Registered: ‎04-14-2009
My Device: Not Specified

Re: End Of Media Fired Too Soon in OS 5

In this case, all I can suggest is that you try a DataSource+SourceStream implementation. Most of the work you've done in your PrivateInputStream translates easily into SourceStream.read() method. See if this approach works on pre-5.0 and 5.0+ OSes.

Developer
rihan007
Posts: 455
Registered: ‎01-14-2009
My Device: Apple iPhone 3GS 16GB

Re: End Of Media Fired Too Soon in OS 5

 sure  i shall have a play with it and let you know the outcome very soon. Cheers

Developer
rihan007
Posts: 455
Registered: ‎01-14-2009
My Device: Apple iPhone 3GS 16GB

Re: End Of Media Fired Too Soon in OS 5

I implemented the source stream and datasource . now the issue is end of media is not fired at all.

 

the events are

 

Event:....................com.rim.playableStreams
Event:....................com.rim.mediaLoaded

 

Event:....................started

Event:....................com.rim.timeUpdate
SMP[-2126569665,MP: h=0]: BUFFERING = 100
Event:....................bufferingStopped

 


Event:....................com.rim.timeUpdate

 

SMP[-2126569665,MP: h=0]: BUFFERING = 0
Event:....................bufferingStarted
SMP[-2126569665,MP: h=0]: BUFFERING = 0
Event:....................bufferingStarted
SMP[-2126569665,MP: h=0]: BUFFERING = 0
Event:....................bufferingStarted
SMP[-2126569665,MP: h=0]: BUFFERING = 0 (this repeats and doesnt stop... ) but the audio has ended even before thte buffering started thingy starts.

 

.

The AMRDataSource is given below

 

 

import MobileJob.*;
 import java.io.IOException;
import javax.microedition.media.Control;
import javax.microedition.media.protocol.DataSource;
import javax.microedition.media.protocol.SourceStream;
 import net.rim.device.api.io.NoCopyByteArrayOutputStream;

public class AMRDataSource extends DataSource {
       
       public final static String CONTENT_TYPE = "audio/amr";
 
       private final static byte[] AMR_HEADER = {(byte) 0x23, (byte) 0x21, (byte) 0x41, 
                      (byte) 0x4d, (byte) 0x52,(byte) 0x0a};  
       
       private NoCopyByteArrayOutputStream baos;
      
       private AMRSourceStream amrSourceStream;
 
       private volatile int totalRead;

       private volatile boolean _stop = false;
       
     
       public AMRDataSource(String locator,long startTime) {
                super(locator);
                
                this.baos = new NoCopyByteArrayOutputStream(); 
            this.amrSourceStream = new AMRSourceStream(CONTENT_TYPE, baos);
          try {
                  //baos.write(AMR_HEADER);
                  MobileJob job=new MobileJob(Descriptor.getInstance().getlocator());
                  baos.write(job.getAMRByteArray((int)startTime));
                  baos.flush();
                } catch (IOException e) {
                      System.out.println(e);
         }  
          catch (Exception e) {
                      System.out.println(e);
         }  
         
       }
 

     public void connect() throws IOException {
             // TODO Auto-generated method stub
             
       }

     public void disconnect() {
             try {
                  stop();
                        baos.close();
                  amrSourceStream = null;
             } catch (IOException e) {
                      System.out.println(e);
         }
      }


    public SourceStream[] getStreams() {
           return new SourceStream[] {amrSourceStream 
            };
     }

     public void start() throws IOException {
               // TODO Auto-generated method stub
             
       }

     public void stop() throws IOException {
                _stop = true;
  }

     
       public String getContentType() {
               return amrSourceStream.getContentDescriptor().getContentType();
     }

     public Control getControl(String controlType) {
                // TODO Auto-generated method stub
             return null;
   }

     public Control[] getControls() {
               // TODO Auto-generated method stub
             return null;
   }

     public NoCopyByteArrayOutputStream getBaos() {
         return baos;
   }
}

 

 

The AMRSourceSTream is given below

 

 

 
package Main; 
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Datagram;
import javax.microedition.io.Connector;
import javax.microedition.media.Control;
import javax.microedition.io.SocketConnection;
import javax.microedition.io.DatagramConnection;
import javax.microedition.media.protocol.SourceStream;
import javax.microedition.media.protocol.ContentDescriptor;
import net.rim.device.api.io.NoCopyByteArrayOutputStream;

public class AMRSourceStream implements SourceStream {

     private ContentDescriptor _contentDescriptor;
  private long currentPosition;
  private NoCopyByteArrayOutputStream stream;
    
       public AMRSourceStream(String contentType, NoCopyByteArrayOutputStream stream) {
             _contentDescriptor = new ContentDescriptor(contentType);
               this.stream = stream; 
                 currentPosition = 0; 
      }
      
       public ContentDescriptor getContentDescriptor() {
              return _contentDescriptor;
     }
      
       public long getContentLength() {
               return -1;
     }

     public int getSeekType() {
             return SEEKABLE_TO_START;
      }

     public int getTransferSize() {
         return 16;
     } 
public int read(byte[] b, int off, int len) throws IOException {
            if (len < 1) {
            return 0;
            }
            
            final int streamSize = stream.size();
            final int currentPosition = (int) this.currentPosition;
            final int bytesToReturn = Math.min(streamSize - currentPosition, len);
            if (bytesToReturn < 1) {
            
            return 0;
            }
            
            System.arraycopy(stream.getByteArray(), currentPosition, b, off, bytesToReturn);
            
            this.currentPosition += bytesToReturn;
            
            return bytesToReturn;
}
     public long seek(long where) throws IOException {
              if (where <= 0) this.currentPosition = 0;
              else if (where < stream.size()) this.currentPosition = where;
          else {
                 System.out.println("Seek request beyond buffer size: " + Long.toString(where));
         }
              return this.currentPosition; 
  }

     public long tell() {
           return currentPosition; 
       }

     public Control getControl(String controlType) {
                // TODO Auto-generated method stub
             return null;
   }

     public Control[] getControls() {
               // TODO Auto-generated method stub
             return null;
   }

     
}

 Please help

 

Developer
Posts: 1,474
Registered: ‎04-14-2009
My Device: Not Specified

Re: End Of Media Fired Too Soon in OS 5

Your SourceStream.read doesn't appear to block when there's no data available...

Developer
rihan007
Posts: 455
Registered: ‎01-14-2009
My Device: Apple iPhone 3GS 16GB

Re: End Of Media Fired Too Soon in OS 5

Ok . so what should i return instead of return 0 to fire the endofmedia.?