Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I stream music from a file inside encrypted zip without decompressing the entire file?

I have to play the audio file. Which is in zip file, which is the present in sdcard. And the audio file is encrypted. So while decrypting the audio, i will get the data in the inputstream.

I dont want to unzip because it eats space on disk.

As i have investigated i did not got clues on how to play audio directly if i have stream. Its only possible over network. Which is not in this case.

So what i thought is to spawn a thread which will keep appending data(bytes) to the file. As this starts, I am calling MediadPlayer to start its job.

Media player does fine. Fun starts here: Suppose if audio file in 6min - 5MB. The buffering might have happen for 2MB. In the seek bar i can see for 2min as my max duration. This is perfectly right. When the buffering is still continue.. happening, I want to update the time in seek bar and its length (Seek bar length) is directly proportional for the given time. how do i go about this.

I tried OnBufffering for this, it did not work. I guess actually its for streaming audio file, if its played over a network.

Please give me some simple solution, how to get this done? Don't ask me to override MediaPlayer class and work on it.

Any help is appreciated. Let me know if you need more clarity on this.

public class NotesAudDisplay extends Activity implements OnPreparedListener, MediaController.MediaPlayerControl{
    private static final String TAG = "activity-NotesAudioDisplay";

    private String audioFilePath;
    private String notesFileName;
    private String mcfFileName;
    private String key;

    private SeekBar seekBarProgress;

    private NotesElement notesElement = null;
    private String notesTittle = "", notesHeading = "";
    private TextView heading_tv, playerStatus_tv;
    private QuesBuilder qb = null;

    private MediaPlayer mediaPlayer = null;
    private MediaController mediaController;

    private Drawable play_butt, pause_butt;
    private ProgressDialog pd;
    private Resources res = null;

    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.audio_notesdisplay);

        res = getResources();
        play_butt = res.getDrawable(R.drawable.play);
        pause_butt = res.getDrawable(R.drawable.pause);

        heading_tv = (TextView) findViewById(R.id.notesHeading_tv);
        playerStatus_tv = (TextView) findViewById(R.id.playerStatus_tv);

        Intent intent = getIntent();
        notesTittle = intent.getStringExtra("notesTittle");
        notesFileName = intent.getStringExtra("notesFileName");
        mcfFileName = intent.getStringExtra("mcfFileName");
        key = intent.getStringExtra("key");

        TextView tittle_tv = (TextView) findViewById(R.id.notesTittle_tv);
        tittle_tv.setText(notesTittle);

        NotesXMLParser nxp = new NotesXMLParser(this, notesFileName,
                mcfFileName, key);
        nxp.OpenXmlDocument();
        notesElement = nxp.getNotesContent();
        Log.d("TAG", "notesele:" + notesElement);
        if (notesElement != null) {
            notesHeading = notesElement.getHeading();
            heading_tv.setText(notesHeading);

            QuesBuilderSet qbs = notesElement.getNotesStatement();
            ArrayList quesBuilder = qbs.getQuesBuilderSet();
            if (quesBuilder != null) {
                Log.d(TAG, " quesBuilder len:" + quesBuilder.size());
                for (int i = 0; i < quesBuilder.size(); i++) {
                    qb = (QuesBuilder) quesBuilder.get(i);
                    if (qb.getType() == QuesBuilder.SPEECH) {
                        Log.d(TAG, " AUDIO");

                        String file = qb.getQuesSpeech();
                        File f = createTmpAudioFile(file);

                        boolean decrypt_result = false;
                        if (f != null) {
                            new LongOperation().execute(f);
                            Log.d(TAG,"****before long operation****");
                            try {
                                Log.d(TAG,"****before thread operation****");
                                Thread.sleep(3000);
                                Log.d(TAG,"****after thread operation****");
                                setContent();

                            } catch (Exception e) {
                                Log.d("InstructionForm", "Sleep thread fails");
                            }
                            Log.d(TAG,"****after catch****");
                        } else {
                            heading_tv.setText(notesHeading
                                    + " Unable to play the audio.");
                        }

                    } else {
                        Log.d(TAG, " other:" + qb.getType());
                    }
                }
            }
        }
    }// onCreate

    public void setContent() {
        mediaController = new MediaController(NotesAudDisplay.this);
        mediaPlayer = new MediaPlayer();
        Log.d(TAG,"***GOING TO PREP STATE***");
        mediaPlayer.setOnPreparedListener(NotesAudDisplay.this);
        Log.d(TAG,"***DONE WITH PREP STATE***");
        try {
            mediaPlayer.setDataSource(audioFilePath);
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.prepareAsync();
            mediaPlayer.start();
            playerStatus_tv.setText("Playing.. . ");
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private File createTmpAudioFile(String file) {
        DBAdapter dba = new DBAdapter(NotesAudDisplay.this);
        dba.open();
        String mobiDataPath = dba.get_mobidata_path();
        dba.close();
        audioFilePath = mobiDataPath + "/" + file;
        Log.d(TAG, "tmp audio filePath:" + audioFilePath);
        File f = null;
        try {
            f = new File(audioFilePath);
            return f;
        } catch (Exception e) {
            f = null;
            Log.d(TAG, " exception caught in creating audio file on sdcard");
        }
        return null;
    }

    private class LongOperation extends AsyncTask<File, Void, Boolean> {

        @Override
        protected void onPreExecute() {
            // TODO run small wheel
            // show_wheel();
        }

        @Override
        protected Boolean doInBackground(File... arg0) {
            DecryptZipReader dr = new DecryptZipReader();
            File f = arg0[0];
            Log.d(TAG, "*********copying start*********");
            boolean res = dr.getDecryptFileStream(NotesAudDisplay.this,
                    qb.getQuesSpeech(), mcfFileName, key, f);
            return new Boolean(res);
        }

        @Override
        protected void onPostExecute(Boolean result) {
            // close_wheel();
            Log.d(TAG, "*********copying stop*********");

        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mediaPlayer != null) {
            mediaPlayer.release();
            mediaPlayer = null;
        }

    }

    @Override
    protected void onStop() {
      super.onStop();
      mediaPlayer.stop();
      mediaPlayer.release();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
      //the MediaController will hide after 3 seconds - tap the screen to make it appear again
      mediaController.show(0);
      return false;
    }

    //--MediaPlayerControl methods----------------------------------------------------
    public void start() {
      mediaPlayer.start();
    }

    public void pause() {
      mediaPlayer.pause();
    }

    public int getDuration() {
      Log.d(TAG,"***duration:"+mediaPlayer.getDuration());
      return mediaPlayer.getDuration();
    }

    public int getCurrentPosition() {
      return mediaPlayer.getCurrentPosition();
    }

    public void seekTo(int i) {
      mediaPlayer.seekTo(i);
    }

    public boolean isPlaying() {
      return mediaPlayer.isPlaying();
    }

    public int getBufferPercentage() {
      return 0;
    }

    public boolean canPause() {
      return true;
    }

    public boolean canSeekBackward() {
      return true;
    }

    public boolean canSeekForward() {
      return true;
    }
    //--------------------------------------------------------------------------------

    public void onPrepared(MediaPlayer mediaPlayer) {
      Log.d(TAG, "*********onPrepared*********");
      mediaController.setMediaPlayer(this);
      mediaController.setAnchorView(findViewById(R.id.main_audio_view));

      handler.post(new Runnable() {
        public void run() {
          mediaController.setEnabled(true);
          mediaController.show(0);
        }
      });
    }
}
like image 615
maxwells Avatar asked Dec 24 '11 12:12

maxwells


People also ask

Can you zip audio files?

To zip an audio file in Windows: Right-click on the file and select Send To. Choose Compressed (zipped) folder. Name your new zipped folder.

How do I open Zip files with mp3?

To open a Zipped Folder, right-click, and Extract All. Click the file you want to play. If you have an app that works with ZIP archives, download the zipped folder directly to your device and extract the files. You may also download the ZIP file to your computer, unzip and copy the files to your mobile device.

How do I hide the contents of a ZIP file?

To hide a file from common Zip applications, simply un-check it. To remove a file from the archive, mark it in the left list and press [delete]. You can extract any files, hidden or not, by marking them and clicking "Extract selected files". "Save changes" asks for a new file name.


1 Answers

Afaik, you could take a FileDescriptor from a zip without extracting using the ZipResource Library from Google, it is intended for expansion packages only, but it works perfectly if you just store the items and not compress it (zip -r -n .mp3:.png:.txt destiny origin).

The FileDescriptor is ready to use with MediaPlayer, but if its encrypted maybe having two descriptors might help you to optimize the decryption flux.

public ZipResourceFile getExpansionFiles(Context context){


 ZipResourceFile expansionFile = null;
try {
expansionFile = new ZipResourceFile(                                
    Environment.getExternalStorageDirectory() + "/MyFolder" + "/" + "/MyFile" + ".zip");

} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}}

then use: ZipResourceFile z = getExpansionFiles(mContext);

AssetFileDescriptor afd = z.getAssetFileDescriptor(mItem +".mp3");

I hope it helps, anyway, are you sure that you don't want to wait until file is completely decrypted, and then play it without worrying about all this on-the-fly headache?

like image 199
meyo Avatar answered Oct 29 '22 00:10

meyo