播放WAV / MP3输出TTS与的MediaController [英] Play wav / mp3 output from TTS with mediacontroller

查看:522
本文介绍了播放WAV / MP3输出TTS与的MediaController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图输出TTS在Android中的MP3或WAV,然后通过媒体播放器播放。该TTS输出到文件中运作良好,MP3文件可在SD卡在以下位置:

I am trying to output an MP3 or wav from TTS in android which then plays back via mediaplayer. The TTS output to file works well and the mp3 file is available on the sdcard at the following location:

/sdcard/tmp/tmp.mp3

/sdcard/tmp/tmp.mp3

我的问题是音频文件只能播放一次,如果用户重新选择播放按钮,然后在文件犯规发挥。

The problem I have is the audio file will only play once, if the user reselects the "Play" button then the file doesnt play.

我有第二个问题是,未启用表示文件期间播放的媒体控制器/用户触摸屏幕。
在code的重要部分如下:

The second problem I have is that the media controller isnt showing while the file is playing / user touches the screen. The important parts of the code are below:

   //audio file playback here
    public MediaPlayer mediaPlayer;
    public MediaController mediaController;
    private Handler handler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {

       //mediaplayer stuff

        mediaPlayer = new MediaPlayer();
        mediaPlayer.setOnPreparedListener(this);

        mediaController = new MediaController(this);
}

播放按钮的onclick是这样的:

The play button onclick looks like this:

 String text = inputText.getText().toString();
                    if (text!=null && text.length()>0) {
                //  tts.speak(text, TextToSpeech.QUEUE_ADD, null);

                    //trial synth to file here
                    HashMap<String, String> myHashRender = new HashMap<String, String>();
                    myHashRender.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, text);
                    String tempDestFile = Environment.getExternalStorageDirectory().getPath()+"/tmp/tmp.wav";
                    tts.synthesizeToFile(text, myHashRender, tempDestFile);
                    //todo hand to media player for play pause etc
                    //todo handle delete of the file at some stage - creation of activity?

                    tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
                     public void onDone(String utteranceId){
                         // Speech file is created
                         // Initializes Media Player
                        Log.d("File created ", "init mediaplayer then call playAudio()");
                         initializeMediaPlayer();
                         //now play the audio
                        playAudio();
                     }

@Override
                public void onError(String utteranceId) {
                    // TODO Auto-generated method stub

                }
                @Override
                public void onStart(String utteranceId) {
                    // TODO Auto-generated method stub

                }

                });
                }else{

                }
        }

有关媒体播放器的INITIALISE看起来是这样的:

The initialise for mediaplayer looks like this:

private void initializeMediaPlayer(){
    String fileName = Environment.getExternalStorageDirectory().getAbsolutePath() + "/tmp/tmp.wav";

    Uri uri  = Uri.parse("file://"+fileName);

    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

    try {
        mediaPlayer.setDataSource(getApplicationContext(), uri);
        mediaPlayer.prepare();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

playAudio:

playAudio:

  private void playAudio() {
    mediaPlayer.start();
            mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

                public void onCompletion(MediaPlayer mediaPlayer) {
                    Log.d("MediaPlayer", " finished so release");
                    mediaPlayer.release();
                }
            });


        }

        @Override
        protected void onStop() {
          super.onStop();
          mediaController.hide();
          mediaPlayer.stop();
          mediaPlayer.release();
        }

       public void start() {
          mediaPlayer.start();
        }

        public void pause() {
          mediaPlayer.pause();
        }

        public int 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("onPrepared", " is running");
            mediaController.setMediaPlayer(this);
            mediaController.setAnchorView(findViewById(R.layout.activity_main));

            handler.post(new Runnable() {
              public void run() {
                mediaController.setEnabled(true);
                mediaController.show();
              }
            });
          }

最后ouTouchEvent是在这里:

Finally the ouTouchEvent is here:

 public boolean onTouchEvent(MotionEvent me) {
            mediaController.show();
            return gDetector.onTouchEvent(me);

            }

LogCat中似乎表明该文件被播放后,媒体播放器被释放并准备再次发挥,这是logcat的输出,当我尝试播放文件两次:

Logcat would seem to suggest the mediaplayer is being released after the file is played and is ready to play again, this is the logcat output when i try to play the file twice:

12-21 08:39:18.025: V/MediaPlayer-JNI(26717): isPlaying: 1
12-21 08:39:18.025: V/MediaPlayer-JNI(26717): getCurrentPosition: 2229 (msec)
12-21 08:39:18.025: V/MediaPlayer(26717): getDuration
12-21 08:39:18.030: V/MediaPlayer-JNI(26717): getDuration: 6288 (msec)
12-21 08:39:22.320: V/MediaPlayer(26717): message received msg=2, ext1=0, ext2=0
12-21 08:39:22.320: V/MediaPlayer(26717): playback complete
12-21 08:39:22.320: V/MediaPlayer(26717): callback application
12-21 08:39:22.325: D/MediaPlayer(26717):  finished so release
12-21 08:39:22.325: V/MediaPlayer-JNI(26717): release
12-21 08:39:22.325: V/MediaPlayer(26717): back from callback
12-21 08:39:22.330: V/MediaPlayer(26717): setListener
12-21 08:39:22.330: V/MediaPlayer(26717): disconnect
12-21 08:39:22.345: V/MediaPlayer(26717): destructor
12-21 08:39:22.350: V/MediaPlayer(26717): disconnect
12-21 08:39:26.465: D/File created(26717): init mediaplayer then call playAudio()
12-21 08:39:26.465: V/MediaPlayer-JNI(26717): setAudioStreamType: 3

在总结我的2个问题是:

In summary my 2 questions are:

为什么只有音频每次播放的ImageButton是pressed时间播放一次不?

Why does the audio only play once and not each time the Play ImageButton is pressed?

编辑:

由于以下由Dave部分回答媒体现在每个用户presses播放按钮时播放。该mediacontrols仍然没有显示触摸虽然。

Thanks to the part answer below by Dave the media now plays each time the user presses the play button. The mediacontrols still are not showing on touch though.

如何修改我的code所以mediacontrols显示标准的播放暂停停止寻求等?

How should I modify my code so the mediacontrols show standard play pause stop seek etc?

感谢您的帮助,这是我在Android的媒体播放器第一次尝试;

Thanks for the help, this is my first attempt with mediaplayer in android;

刘德华

推荐答案

您需要更多地关注到的MediaPlayer 的的状态机,并与它更仔细地围绕设计你的互动。具体而言,你不能叫发布在完成回调,并期望能够再次使用相同的的MediaPlayer。

You need to pay more attention to the MediaPlayer's state machine and design your interaction with it more carefully around that. To be specific, you cannot call release in the completion callback and expect to be able to use the same MediaPlayer again.

您可以改为调用重置在完成回调并办理code你在 initializeMediaPlayer 有再次。或者可以选择,你可以尝试寻找到零,以避免重新preparing源(虽然preparing本地文件是在性能方面可以忽略不计)。

You can instead call reset in the completion callback and go through the code you have in initializeMediaPlayer again. Or alternatively, you can try seeking to zero to avoid re-preparing the source (although preparing a local file is negligible in terms of performance).

编辑:
关于您的的MediaController 问题......它可以在模拟器有点靠不住。我有几个建议。

About your MediaController problem... it can be a bit wonky in the emulator. I have a few suggestions.

1),基本上不会使用 getApplicationContext(),特别是从没有一个活动内(这已经是上下文)。 (这可能不利于获取控制来展示,但只是一般的提示。)

1) Basically never use getApplicationContext(), especially not from inside an Activity (which already is a Context). (This probably doesn't help get the controller to show, but is just a general tip.)

2)你传入 R.layout.activity_main findViewById 。我不认为这是正确的。它应该是 R.id .___ 的布局中定义的视图的ID。您可以使用 Android的定义标识:在布局XML ID 标签

2) You are passing R.layout.activity_main to findViewById. I don't think that's correct. It should be R.id.___ for the ID of a view defined inside the layout. You can define the IDs with the android:id tag in the layout XML.

3)我无法得到控制器传递一个空的LinearLayout 的ID时显示。如果你想使用的布局,你可能需要把某种观点在里面。我把的TextView 里面和中提琴,我有一个控制器。它不显示时间不长,所以要注意。有可能是为显示超时设置的参数。

3) I could not get the controller to show when passing the ID of an empty LinearLayout. If you want to use a layout, you may need to put some kind of view inside it. I put a TextView inside it and viola, I had a controller. It doesn't show for long, so pay attention. There may be a parameter to set for the display timeout.

这篇关于播放WAV / MP3输出TTS与的MediaController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆