2011-12-24 21 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”);

我希望它有帮助,无论如何,你确定你不想等到文件完全解密,然后播放它而不用担心所有这些飞行中的头痛吗?

相关问题