【问题标题】:Play audio between points A and B在 A 点和 B 点之间播放音频
【发布时间】:2016-08-30 07:36:26
【问题描述】:

如何设置从和到时间戳标记并在音频文件的这两点之间播放媒体?我在 Android 中看不到 MediaPlayer 的侦听器 API。想知道如何才能实现这一目标?

我的情况是这样的: 将音频文件分成许多这样的部分,让用户按照自己的意愿交互式地播放/重播其中的部分内容。

例如,假设一个小音频文件被分成 3 个部分(A---B---C---D),即 AB、BC 和 CD。用户选择部分 BC 并选择玩。然后音频从 B 点开始播放,并在到达 C 点时停止。用户可以再次播放 BC 部分或选择继续播放下一部分。

虽然更容易确定起点并使用mediaPlayer.seekTo(int) API,但我如何才能让音频在终点停止?最好的方法是什么?

非常感谢您的帮助。

【问题讨论】:

  • 我知道实现这一点的一种方法是使用Handler 并每秒跟踪mediaPlayer.getCurrentPosition() 以查看它是否已达到目标点?还有比这个更好的方法吗?

标签: android audio android-mediaplayer


【解决方案1】:

我认为你可以使用 mediaPlayer.seekTo(int msec)

mediaPlayer.setLooping(true); 
mediaPlayer.seekTo(0); 
mediaPlayer.start(); 

【讨论】:

  • 除了@user8430'th answer,使用from,使用seekTo,使用to使用播放器的onProgress监听器,一旦达到要求的时刻就停止播放。
  • @VladMatvienko,不幸的是,mediaPlayer 上没有 onProgress 监听器:(
  • @karthiks:你看到这个android-er.blogspot.kr/2012/06/…了吗?我觉得对你有用
  • @karthiks,你说得对,我忘了没有。但您可以随时查看进度并停止播放。
【解决方案2】:

我用计时器来做类似的事情。以下代码假定您有一个带有一个按钮的布局(ID 为“按钮”),并且您的 mp3 文件是“myMp.mp3”,它位于raw 文件夹中。
play 方法获取两个参数,均以毫秒为单位 - 起点和持续时间,但您可以轻松地将其更改为起点和终点。

private MediaPlayer mediaPlayer;
private Timer timer;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Button btnStart = (Button) findViewById(R.id.button);
    mediaPlayer = MediaPlayer.create(this, R.raw.myMp);

    btnStart.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            preparePlayer();
            play(20000, 3000);
        }
    });        
}

private void preparePlayer() {
    try {
        mediaPlayer.prepareAsync();
    } catch (Exception e) {
        //Handle exception
    }
}

private void play(int start, int duration) {
    mediaPlayer.seekTo(start);
    mediaPlayer.start();
    timer = new Timer();
    timer.schedule(new PlayerTask(), duration);
}

class PlayerTask extends TimerTask {

    @Override
    public void run() {
        mediaPlayer.stop();
    }
}    

【讨论】:

【解决方案3】:

我认为你可以使用Handler.sendMessageDelayed。当您start mediaPlayer 时调用该函数。假设您想播放 X 秒,您可以将 X - 1 作为参数传递(-1 作为缓冲区)。那是因为我们必须考虑不同的因素,消息调度,媒体播放器启动延迟等。当消息到达时,您检查getCurrentPosition。如果还有时间,则每隔几毫秒检查一次位置。

如果不需要精确,可以直接传X,消息到达后停止。

【讨论】:

    【解决方案4】:

    我的实现方式如下:

    private MediaPlayer mediaPlayer;
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            mediaPlayer.pause();
            playPauseButton.setText(R.string.play);
        }
    };
    
    private void play(int start, int duration) {
        mediaPlayer.seekTo(start);
        handler.postDelayed(runnable, duration);
    }
    

    我已经复制了与此上下文相关的代码的关键部分。虽然我这样做了,但我对这个实现并不特别满意,因为这仍然不准确。

    我正在寻找是否有人使用替代 API 来实现此准确性,可能是通过使用 Android 的 AudioTrack API 或类似的东西。

    据我所知,这似乎是目前最好的替代方案。如果我找到更好的方法,我会更新这篇文章,在此之前,我希望这对你有帮助,就像它对我有帮助一样。干杯!

    【讨论】:

      猜你喜欢
      • 2013-08-08
      • 1970-01-01
      • 2013-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多