简体   繁体   English

如何从加密zip文件中传输音乐而不解压缩整个文件?

[英]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. 这是在zip文件中,这是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. 当这开始时,我打电话给MediadPlayer开始工作。

Media player does fine. 媒体播放器没问题。 Fun starts here: Suppose if audio file in 6min - 5MB. 乐趣从这里开始:假设音频文件在6分钟 - 5MB。 The buffering might have happen for 2MB. 缓冲可能发生在2MB。 In the seek bar i can see for 2min as my max duration. 在搜索栏中,我可以看到2分钟作为我的最大持续时间。 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. 我为此尝试了OnBufffering,它没有用。 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. 不要让我覆盖MediaPlayer类并对其进行处理。

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);
        }
      });
    }
}

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). Afaik,您可以从zip中获取FileDescriptor,而无需使用Google的ZipResource库提取,它仅适用于扩展包,但如果您只存储项目而不压缩它,它可以正常工作(zip -r -n .mp3: .png:.txt命运之源)。

The FileDescriptor is ready to use with MediaPlayer, but if its encrypted maybe having two descriptors might help you to optimize the decryption flux. FileDescriptor已准备好与MediaPlayer一起使用,但如果其加密可能有两个描述符可能会帮助您优化解密通量。

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); 然后使用:ZipResourceFile z = getExpansionFiles(mContext);

AssetFileDescriptor afd = z.getAssetFileDescriptor(mItem +".mp3"); 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? 我希望它有所帮助,无论如何,你确定你不想等到文件被完全解密,然后播放它而不用担心所有这些即时头痛?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM