【问题标题】:Play Byte array in MediaPlayer - Android在 MediaPlayer 中播放字节数组 - Android
【发布时间】:2012-06-10 03:13:43
【问题描述】:

我正在尝试使用 MediaPlayer 播放音频文件。我想在 MediaPlayer 中播放字节数组。我怎样才能做到这一点?我检查了this

 public void writeSamples(byte[] samples, int length) 
{
  //  track.write( samples, 0, length);
    File tempMp3;
    try {
    tempMp3 = File.createTempFile("kurchina", ".mp3");
      tempMp3.deleteOnExit();
      FileOutputStream fos = new FileOutputStream(tempMp3);
      fos.write(samples);
      fos.close();
      // Tried reusing instance of media player
      // but that resulted in system crashes...  
      MediaPlayer mediaPlayer = new MediaPlayer();

      // Tried passing path directly, but kept getting 
      // "Prepare failed.: status=0x1"
      // so using file descriptor instead   
      FileInputStream fis = new FileInputStream(tempMp3);
      mediaPlayer.setDataSource(fis.getFD());
      mediaPlayer.prepare();
      mediaPlayer.start();
      } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    }

但它没有播放音频。它只是在 SD 卡中生成许多文件。并给出这个错误

 06-06 11:02:59.191: E/MediaPlayer(1831): Unable to to create media player
 06-06 11:02:59.191: W/System.err(1831): java.io.IOException: setDataSourceFD failed.:      status=0x80000000
 06-06 11:02:59.201: W/System.err(1831):  at    android.media.MediaPlayer.setDataSource(Native Method)
 06-06 11:02:59.201: W/System.err(1831):  at   android.media.MediaPlayer.setDataSource(MediaPlayer.java:749)
 06-06 11:02:59.201: W/System.err(1831):  at   org.vinuxproject.sonic.SonicTest$1.run(SonicTest.java:178)
 06-06 11:02:59.201: W/System.err(1831):  at java.lang.Thread.run(Thread.java:1096)

请帮助我。任何形式的帮助表示赞赏。

谢谢

【问题讨论】:

  • 在此处添加您的代码 sn-p,有人会提供帮助。
  • 我建议尝试 setDataSource 变体,它除了 FD 之外还需要一个偏移量和长度。生成的 mp3 文件是否在音乐应用程序中播放?此外,deleteOnExit 在 Android/Dalvik 中没有用。
  • 没有文件没有在我的应用程序中播放。请帮帮我
  • samples 数组是否包含 mp3 编码数据,还是仅包含原始 PCM 数据?
  • 如果您使用createTempFile(String, String, File) 指定目录,这是否有效?外部/内部有区别吗?现在在哪里创建临时文件?

标签: android


【解决方案1】:

试试这个:

private void playMp3(byte[] mp3SoundByteArray) 
{
    try 
    {

        File path=new File(getCacheDir()+"/musicfile.3gp");

        FileOutputStream fos = new FileOutputStream(path);
        fos.write(mp3SoundByteArray);
        fos.close();

        MediaPlayer mediaPlayer = new MediaPlayer();

        FileInputStream fis = new FileInputStream(path);
        mediaPlayer.setDataSource(getCacheDir()+"/musicfile.3gp");

        mediaPlayer.prepare();
        mediaPlayer.start();
    } 
    catch (IOException ex) 
    {
        String s = ex.toString();
        ex.printStackTrace();
    }
}

【讨论】:

    【解决方案2】:

    在文件上写入一个字节后: 你可以从这个功能玩:

     void playSound(int resid) {
            MediaPlayer eSound = MediaPlayer.create(context, resid);
            Resources res = context.getResources();
            AssetFileDescriptor afd = res.openRawResourceFd(resid);
            eSound.reset();
            eSound.setAudioStreamType(AudioManager.STREAM_SYSTEM);
            try {
                eSound.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(),
                        afd.getLength());
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                eSound.prepare();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            eSound.start();
        }
    

    您可以从这里获取文件信息:

    byte[] getFileInformation(String filepath) {
            MediaPlayer eSound = MediaPlayer.create(context, Uri.parse(filepath));
            eSound.reset();
            eSound.setAudioStreamType(AudioManager.STREAM_SYSTEM);
            try {
                eSound.setDataSource(filepath);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                eSound.prepare();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            int duration = eSound.getDuration() / 1000;
    
            int height = 480;
            int width = 640;
            height = eSound.getVideoHeight();
            width = eSound.getVideoWidth();
    
            eSound.release();
            File f = new File(filepath);
            int size = (int) f.length();
            byte[] b = new byte[16];
            System.arraycopy(convertIntToByte(size), 0, b, 0, 4);
            System.arraycopy(convertIntToByte(duration), 0, b, 4, 4);
            System.arraycopy(convertIntToByte(width), 0, b, 8, 4);
            System.arraycopy(convertIntToByte(height), 0, b, 12, 4);
            return b;
        }
    

    【讨论】:

      【解决方案3】:

      根据您的 cmets,您正在使用 WAV 文件进行流式传输。文件开头的常规WAV has a header 和文件的其余部分是纯数据。如果您不包括标题部分,则需要将其中的参数提供给能够解释数据的播放器(通道数、每秒样本数、块大小等)。因此,WAV文件本身是不可流式传输的,必须将参数输入到播放器中。

      另一方面,MPEG-4 已被指定为能够流式传输。它包含可以单独播放的可识别的段,因此只要数据块包含头部,它之后的数据就可以播放。除了压缩比好之外,这也是很多网络电台使用它的原因之一。

      MediaPlayer 在 Android 中是一个高级组件,无法访问播放 WAV 块所需的低级参数。如果您需要源是 WAV 并且不能使用其他 streamable formats,那么您可以尝试使用 AudioTrack 类或 OpenSL ES 以获得更低级别的访问权限。 对于 AudioTrack,这是一个非常好的教程:http://audioprograming.wordpress.com/2012/10/18/a-simple-synth-in-android-step-by-step-guide-using-the-java-sdk/

      【讨论】:

      • 嗯...audioTrack 听起来像是要走的路。
      • 如果我能提供帮助,请告诉我。
      • wordpress 链接已“失效”,因为该博客现在是私有的
      • @ForceGaia 我们可能会尝试请求访问博客或尝试找到一些新教程。如果您有任何建议,请随时编辑帖子。
      猜你喜欢
      • 1970-01-01
      • 2017-05-19
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-19
      相关资源
      最近更新 更多