当前位置: 首页 > 知识库问答 >
问题:

使用mediacontroller从TTS播放wav/mp3输出

范安歌
2023-03-14

我试图输出一个MP3或wav从TTS在Android,然后通过媒体播放器播放。TTS输出到文件运行良好,MP3文件可在以下位置的SD卡上使用:

/SD卡/tmp/tmp。mp3

我的问题是音频文件只会播放一次,如果用户重新选择“播放”按钮,那么文件就不会播放。

我的第二个问题是,当文件播放/用户触摸屏幕时,媒体控制器不显示。守则的重要部分如下:

   //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如下所示:

 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{

                }
        }

media播放器的初始化如下:

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

播放音频:

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

最后,Outoutchevent在这里:

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

            }

Logcat似乎暗示mediaplayer在文件播放后被释放,并准备再次播放,这是我尝试播放文件两次时的Logcat输出:

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

总而言之,我的两个问题是:

为什么音频只播放一次,而不是每次按下“播放图像”按钮时播放一次?

编辑:

由于Dave给出了下面的部分答案,现在每当用户按下播放按钮时,媒体都会播放。不过,触摸屏上仍然没有显示MediaControl。

我应该如何修改我的代码,以便media acontrols显示标准播放暂停停止寻找等?

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

安迪

共有1个答案

赵昊阳
2023-03-14

您需要更加关注MediaPlayer的状态机,并围绕这一点更仔细地设计与它的交互。具体来说,您不能在完成回调中调用release,并期望能够再次使用相同的MediaPlayer

相反,您可以在完成回调中调用重置,并再次浏览初始化MediaPlayer中的代码。或者,您可以尝试尝试归零以避免重新准备源(尽管准备本地文件在性能方面可以忽略不计)。

编辑:关于你的MediaController问题...在模拟器中可能有点不稳定。我有几点建议。

1)基本上永远不要使用getApplication ationContext(),尤其是不要从活动(已经是Context)内部使用。(这可能无助于让控制器显示,但只是一个一般的提示。)

2) 您正在传递R.layout。活动\u mainfindViewById。我认为那是不对的。布局内定义的视图id应为R.id.u u uu。您可以使用布局XML中的android:id标记定义id。

3)我不能让控制器显示时传递一个空的IDLinearLayout.如果您想使用布局,您可能需要在其中放置某种视图。我把一个TextView里面和Viola,我有一个控制器。它不会显示很长时间,所以要注意。可能存在要为显示超时设置的参数。

 类似资料:
  • 问题内容: 如何在Java应用程序中播放和文件?我正在使用。我尝试在互联网上查找类似以下示例的内容: 但是,这只会播放文件。 问题答案: 如何在Java应用程序中播放和文件?我正在使用。我尝试在互联网上查找类似以下示例的内容: 但是,这只会播放文件。

  • 尝试使用mediacontroller通过url播放音频文件 但我有一个错误: 09-11 10:28:23.970:E/MediaPlayer(912):尝试在没有有效MediaPlayer的情况下调用getDuration 09-11 10:28:23.970:E/MediaPlayer(912):错误(-38,0)09-11 10:28:23.990:E/MediaPlayer(912):尝

  • 问题内容: 我正在尝试编写一个将从Soundcloud URL播放mp3的python脚本 这是我已经做的: 我尝试了许多选项,例如更改格式,频道,费率。而且我只是从扬声器中听到奇怪的声音,我搜索了Google以播放mp3,但没有找到任何信息。 我尝试通过传递mp3中的字节来创建对象,然后仅执行play函数。我没有收到任何错误:脚本正在运行,但没有任何播放。 我正在使用Python 3和Ubunt

  • 当我使用MediaPlayer播放mp3文件时,系统会报告错误日志:。但是RealPlayer是正常的。 我发现它的错误只发生在更高的ROM版本。像4.0版本一样,它有错误。在2.3版中,它没有这个错误。 代码: 日志猫错误:

  • LauncherSplash.dll - plug-in that lets you throw up a splash screen in NSIS installers with fading effects (win2k/xp) and transparency. Designed specially for application launchers, when the launched

  • 我正在尝试使用mediacontroller播放音频。我可以让音频正常工作,但当歌曲开始播放时,我的mediacontroller上的播放按钮不会更新。如果按下mediacontroller上的播放按钮,它会暂停歌曲并查找进度条。然后,如果我按pause,它会再次播放歌曲。我在打电话 这不会更新播放按钮。当我调用start时,如何使按钮变为pause按钮? }