2011-12-24 26 views
8

Tôi phải phát tệp âm thanh. Mà là trong tập tin zip, đó là hiện tại trong sdcard. Và tệp âm thanh được mã hóa. Vì vậy, trong khi giải mã âm thanh, tôi sẽ nhận được dữ liệu trong inputstream.Làm cách nào để phát nhạc từ một tệp trong zip được mã hóa mà không giải nén toàn bộ tệp?

Tôi không muốn giải nén vì nó ăn không gian trên đĩa.

Vì tôi đã điều tra, tôi không có manh mối về cách phát trực tiếp âm thanh nếu tôi có luồng. Chỉ có trên mạng của nó. Mà không phải là trong trường hợp này.

Vì vậy, những gì tôi nghĩ là để sinh ra một chuỗi sẽ tiếp tục chắp thêm dữ liệu (byte) vào tệp. Khi điều này bắt đầu, tôi đang gọi MediadPlayer để bắt đầu công việc của mình.

Trình phát đa phương tiện hoạt động tốt. Fun bắt đầu ở đây: Giả sử nếu tập tin âm thanh trong 6min - 5MB. Việc lưu vào bộ đệm có thể xảy ra với 2MB. Trong thanh tìm kiếm tôi có thể thấy trong 2 phút là thời lượng tối đa của tôi. Điều này là hoàn toàn đúng. Khi bộ đệm vẫn tiếp tục .. xảy ra, tôi muốn cập nhật thời gian trong thanh tìm kiếm và độ dài của nó (Tìm chiều dài thanh) tỷ lệ thuận với thời gian đã cho. làm thế nào để tôi đi về điều này.

Tôi đã thử OnBufffering cho việc này, nó không hoạt động. Tôi đoán thực sự nó cho streaming tập tin âm thanh, nếu nó chơi qua mạng.

Vui lòng cho tôi một số giải pháp đơn giản, cách thực hiện việc này? Đừng yêu cầu tôi ghi đè lên lớp MediaPlayer và làm việc trên đó.

Mọi trợ giúp đều được đánh giá cao. Hãy cho tôi biết nếu bạn cần rõ ràng hơn về điều này.

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

Tôi sẽ xem xét lại những gì bạn đang yêu cầu ... Tạm thời nén tệp âm thanh trong khi bạn phát tệp đó. Hãy nhớ rằng không phải tất cả các tệp âm thanh đều có tốc độ bit cố định và không thể tìm kiếm ngay lập tức. – Brad

+0

Xin chào brad. Tôi xem xét điều đó. Tôi có cơ chế cho điều đó. Tôi đã thay đổi mã của mình. Tôi đang kiểm tra xem tệp có tồn tại hay không và dữ liệu được thu thập là hơn 256 byte. Vì vậy, một phần không phải là một vấn đề. Câu hỏi của tôi là cách cập nhật thanh tìm kiếm. – maxwells

+0

không có một số siêu dữ liệu cho tệp âm thanh cho biết tổng chiều dài của âm thanh (theo thời gian tôi có ý nghĩa, không gian)? Bạn có thể đọc điều đó và đặt độ dài của tệp trực tiếp vào thanh tìm kiếm mà không cần cập nhật giá trị tối đa liên tục. – Genry

Trả lời

1

Afaik, bạn có thể mất một đặc tả tập tin từ một zip mà không cần giải nén bằng cách sử dụng thư viện ZipResource từ Google, nó là dành cho chỉ gói mở rộng, nhưng nó hoạt động hoàn hảo nếu bạn chỉ cần lưu các mục và không nén nó (zip -r -n .mp3: .png: .txt định mệnh gốc).

FileDescriptor đã sẵn sàng để sử dụng với MediaPlayer, nhưng nếu mã hóa của nó có thể có hai bộ mô tả có thể giúp bạn tối ưu hóa luồng giải mã.

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

sau đó sử dụng: ZipResourceFile z = getExpansionFiles (mContext);

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

Tôi hy vọng nó sẽ giúp, dù sao, bạn có chắc chắn rằng bạn không muốn đợi cho đến khi tập tin được giải mã hoàn toàn, và sau đó chơi nó mà không lo lắng về tất cả điều này on-the-fly nhức đầu?

Các vấn đề liên quan