Android Mediadatasource Unexpected Behavior
i was trying to play AAC audio stream in android MediaPlayer, as mentioned here and also here author claimed the problem was ignoring position argument so i made a little setup to
Solution 1:
according to ADTS_Format the buffer should contain an integer number of packets , MediaPlayer
will throw error if it reaches any bad structed packet so the trick is we should Packetize before buffering i can confirm my solution works on ADTS stream:
package CallModule.Media.Convertors;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import CallModule.Media.Objects.ADTSFrame;
import CallModule.Media.Objects.MediaObject;
publicclassInputStreamADTSFrameHarvestimplementsPacketize{
staticprivateintreadLen(byte[] first8bytes){
intfour= first8bytes[3]&0xff; // 2 rightmost bitsintfive= first8bytes[4]&0xff; // all of bitsintsix= first8bytes[5]&0xff; // 3 leftmost bits
six >>=5; // easy! 3 left most bits : 0b1110 >> 1 : 0b111
four = ((four & 0b0011)<<11); // accept only 2 bits (rightmost)
five<<=3; // to get the valuereturn six+four+five;
}
staticprivatebyteFF= (byte) 0b11111111;
publicstatic ADTSFrame harvest(InputStream inps)throws IOException {
ByteArrayOutputStreambos=newByteArrayOutputStream();
byte[] header = {FF,0,0,0,0,0,0,0};
int secondbyte;
int first;
while (true){
bos.reset();
first = inps.read();
if(FF == (byte) first){ // first byte is -1 (singed byte) second byte can be from F0 to FF (-16 to -1)
secondbyte = inps.read();
if(secondbyte>239 && secondbyte<256){ // we found the tail! now we need more 6 bytes to have total of 8 bytes;
header[1] =(byte)secondbyte;
for(int i=0;i<6;i++){
header[2+i] = (byte) inps.read();
}
bos.write(header);
intlen= readLen(header);
byte[] body = newbyte[len-8];
intres=0;
while (res != len-8){
if(res !=0){
System.out.println("Delay");
}
res += inps.read(body,res,len-8-res);
}
bos.write(body);
break ;
}
}else{
System.out.println("Lost something");
}
}
ADTSFrames=newADTSFrame();
s.data= bos.toByteArray();
s.len = s.data.length;
return s;
}
@Overridepublic ADTSFrame packetize(InputStream inps)throws IOException {
return harvest(inps); // rapid call on this method and write to your buffer
}
}
so when we save it to a file (even if last packet is malformed) the setDatasource method will (i guess) trim it before buffering
and MediaPlayer needs to much data before starting (30 packet as i tested) which correspond to 3 seconds (with my sample rate and bitrate).
Post a Comment for "Android Mediadatasource Unexpected Behavior"