MP3 Decoding on Android

前端 未结 4 988
鱼传尺愫
鱼传尺愫 2021-02-01 16:15

We\'re implementing a program for Android phones that plays audio streamed from the internet. Here\'s approximately what we do:

  1. Download a custom encrypted format
4条回答
  •  Happy的楠姐
    2021-02-01 16:55

    To decrypte an encrypted mp3 file before play it. There are 3 ways:

    1,For use MediaPlayer api:

    After Android version M:

    you can play mp3 data in byte array directly by:
    
    //Read encrypted mp3:
    byte[] bytesAudioData =  Utils.readFile(path); // or from a url.
    
    final byte[] bytesAudioDataDecrypted = YourUtils.decryptFileToteArray(bytesAudioData);
    
                    ByteArrayMediaDataSource bds = new ByteArrayMediaDataSource(bytesAudioDataDecrypted) ;
                    mediaPlayer.setDataSource(bds);
    

    Before android Version M:

    //Read encrypted mp3:
    byte[] bytesAudioData =  Utils.readFile(path); // or from a url.
    
    final byte[] bytesAudioDataDecrypted = YourUtils.decryptFileToteArray(bytesAudioData);
    
     File file =new File(dirofyouraudio.mp3");
    
                    FileOutputStream fos = new FileOutputStream(file);
                    fos.write(bytesAudioDataDecrypted);
                    Log.d(TAG, "playSound :: file write to temp :: System. nanoTime() ="+System. nanoTime());
                    fos.close();
    
                    FileInputStream fis = new FileInputStream(file);
                    mediaPlayer.setDataSource(fis.getFD());
    

    2,For AudioTrack api if you use:

      int minBufferSize = AudioTrack.getMinBufferSize(sampleRate,
                AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT);
    
       AudioTrack track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
                AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_16BIT, minBufferSize,
                AudioTrack.MODE_STREAM);
    
        int i = 0;
        byte[] tempMinBufferToRead = new byte[minBufferSize];
    
        try {
    
            byte[] bytesAudioData = Utils.readFile( lastRecordedAudiofilePath);
    
            bytesAudioData = yourUtils.decryptYourFileToByteArray(bytesAudioData);
    
            try {
                fileInputStremForPlay = new FileInputStream( lastRecordedAudiofilePath);
    
                dataInputStreamForPlay = new DataInputStream(new ByteArrayInputStream(bytesAudioData));
    
                track.play();
                while ((i = dataInputStreamForPlay.read(tempMinBufferToRead, 0, minBufferSize)) > -1) {
                    Log.d(LOG_TAG, "mThreadExitFlag= " + mThreadExitFlag);
    
                    if ((mThreadExitFlag == true) || (!audioFilePathInThisThread.equals(lastRecordedAudiofilePath))) {
    
                        m_handler.post(new Runnable() {
                            public void run() {
                                Log.d(LOG_TAG, "startPlaying: break and reset play button ");
    
                                startPlayBtnInToolbar.setEnabled(true);
                                stopPlayBtnInToolbar.setEnabled(false);
                            }
                        });
    
                        break;
                    }
    
                    track.write(tempMinBufferToRead, 0, i);
                }
    
                Log.d(LOG_TAG, "===== Playing Audio Completed ===== ");
                track.stop();
    
                track.release();
    
                dataInputStreamForPlay.close();
    
                fileInputStremForPlay.close();
    
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    

    3, Use MediaExtractor , MediaCodec with AudioTrack , you can set datasource with extractor :

                extractor.setDataSource(this.url);
    

    Or

                extractor.setDataSource(this.Mediadatasource);
    

    ps: The ByteArrayMediaDataSource class:

    import android.annotation.TargetApi;
    import android.media.MediaDataSource;
    import android.os.Build;
    import java.io.IOException;
    
    
    
    import android.content.res.AssetFileDescriptor;
     import android.media.MediaDataSource;
    import android.util.Log;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.io.IOException;
    
    @TargetApi(Build.VERSION_CODES.M)
    public class ByteArrayMediaDataSource extends MediaDataSource {
    
        private static final String TAG = ByteArrayMediaDataSource.class.getSimpleName();
    
    
        private   byte[] data;
    
        public ByteArrayMediaDataSource(byte []data) {
    //        assert data != null;
            this.data = data;
        }
        @Override
        public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
    
    
            if (position >= data.length) {
                return -1; // -1 indicates EOF
            }
            if (position + size > data.length) {
                size -= (position + size) - data.length;
            }
    
            Log.d(TAG, "MediaDataSource size = "+size);
    
    
            System.arraycopy(data, (int)position, buffer, offset, size);
            return size;
    
        }
    
    
    
        @Override
        public long getSize() throws IOException {
    
            Log.d(TAG, "MediaDataSource data.length = "+data.length);
    
            return data.length;
        }
    
        @Override
        public void close() throws IOException {
            // Nothing to do here
            data =null;
        }
    }
    

提交回复
热议问题