2011-12-24 40 views
8

我必須播放音頻文件。這是在zip文件,這是目前在SD卡。並且音頻文件被加密。所以,當解密音頻時,我會在輸入流中獲取數據。如何在不解壓整個文件的情況下從加密zip內的文件流式傳輸音樂?

我不想解壓,因爲它吃光盤上的空間。

正如我所調查,我沒有得到有關如何直接播放音頻,如果我有流的線索。 它只能通過網絡。這不是這種情況。

所以我想是產生一個線程,將保持附加數據(字節)的文件。開始時,我打電話MediadPlayer開始工作。

媒體播放器沒有問題。樂趣從這裏開始:假設音頻文件在6min - 5MB。 緩衝可能發生在2MB。在尋找酒吧,我可以看到2分鐘作爲我的最大持續時間。這是完全正確的。 當緩衝仍然繼續..發生時,我想更新搜索欄中的時間及其長度(搜索欄長度) 與給定時間成正比。我如何去做這件事。

我試過OnBufffering爲此,它沒有工作。我猜實際上它是用於流式音頻文件,如果它通過網絡播放的話。

請給我一些簡單的解決辦法,如何做到這一點?不要求我重寫MediaPlayer課程並開始工作。

任何幫助表示讚賞。讓我知道你是否需要更清晰。

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

我會重新考慮你所要求的...在播放時臨時解壓縮音頻文件。請記住,並非所有音頻文件都是固定比特率,並且不能立即搜索。 – Brad 2011-12-24 17:01:55

+0

嗨,布拉德。我認爲這一點。我有這個機制。我改變了我的代碼。我正在檢查文件是否存在,並且收集的數據超過了256個字節。所以這部分不是問題。我的問題是如何更新搜索欄。 – maxwells 2011-12-24 19:06:26

+0

是不是有一些音頻文件的元數據,它告訴什麼是音頻的總長度(我的意思是,而不是空間)?您可以讀取該文件,並將文件的長度直接放到seekbar中,而不需要不斷更新最大值。 – Genry 2012-10-29 10:09:48

回答

1

據我所知,你可能需要從zip FileDescriptor的,而無需使用來自谷歌的ZipResource庫中提取,它僅用於擴展包,但它完美地工作,如果你只是存儲項目,而不是將其壓縮(壓縮-r -n .mp3:.png:.txt命運起源)。

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

然後使用: ZipResourceFile Z = getExpansionFiles(mContext);

AssetFileDescriptor afd = z.getAssetFileDescriptor(mItem +「。mp3」);

我希望它有幫助,無論如何,你確定你不想等到文件完全解密,然後播放它而不用擔心所有這些飛行中的頭痛嗎?

相關問題