【问题标题】:getDuration() gives 0 output for one file in Android AppgetDuration() 为 Android 应用程序中的一个文件提供 0 输出
【发布时间】:2015-05-12 13:42:49
【问题描述】:

我的应用程序从数据库加载两个音频文件并将它们存储在一个数组中。用户可以通过从单选按钮组中选择一个来播放其中的任何一个。两者都是mp3。一个播放得很好,它已经过去了,总时长显示正确。但相同的功能显示 00:00 其他的总持续时间。在这种情况下,搜索栏也会将其进度更新为 100%,但已正确显示经过的时间并且音频播放正常。有人请告诉是什么问题?为什么会发生这种情况.. 我该如何解决??

audio_urdu 的时间很好。audio_eng 有错误。

    private void updateView(int i) throws JSONException 
{
    idx=0;
    _imgBtnPlay.setClickable(false);
    _imgBtnStop.setClickable(false);

    JSONObject jObject=null;
    jObject=Jarray.getJSONObject(i);
    audioUrl_eng=jObject.getString("audio_eng");
    audioUrl_urdu=jObject.getString("audio_urdu");

    lbl_tDuration.setText("00:00");
    lbl_cDuration.setText("00:00");
    lbl_loading.setText("Loading audio files...");
    loadAudio(audioUrl_eng);
}

// Loading audio files from URL
private void loadAudio(String url) 
{
    // TODO Auto-generated method stub
    mMediaPlayer=new MediaPlayer();
    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);

    try
    {
        mMediaPlayer.setDataSource(url);
        mMediaPlayer.prepareAsync();
    }
    catch(IOException e)
    {
        e.printStackTrace();
    }
    catch (IllegalArgumentException e) 
    {
        e.printStackTrace();
            }
    catch (IllegalStateException e) 
    {
        e.printStackTrace();
    }

    mMediaPlayer.setOnPreparedListener(this);
}

// Notify when audio is ready to be played
@Override
public void onPrepared(MediaPlayer mp) 
{
    // TODO Auto-generated method stub

     audioPlayerList[idx]=mp;
     idx++;
     if (idx == 1)
     {
         audioPlayer = mp;
         lbl_tDuration.setText(mSecToTimer(mp.getDuration()));
         lbl_cDuration.setText(mSecToTimer(mp.getCurrentPosition()));
         updateSeekBar();

         loadAudio(audioUrl_eng);
     }
     if (idx == 2)
     {
         // Enabling the media control buttons
         _imgBtnPlay.setClickable(true);
         _imgBtnStop.setClickable(true);
         rdGrp.setClickable(true);

         lbl_loading.setText("");
         idx = 0;
     }
}

public void onClick(View v) 
{
    switch(v.getId())
    {
        // calling search function
        case R.id.imgBtnSearch:
            onSearchRequested();
            break;

        // when play/pause button is tapped
        case R.id.imgBtnPlay:
            if (audioPlayer.isPlaying())
            {
                    audioPlayer.pause();
                    _imgBtnPlay.setImageResource(R.drawable.ic_action_play);
            }
            else if (audioPlayer!=null)
            {
                audioPlayer.start();
                _imgBtnPlay.setImageResource(R.drawable.ic_action_pause);
                durationHandler.postDelayed(updateSeekBarTime, 100);
            }
            break;

        // when stop button is tapped
        case R.id.imgBtnStop:
            audioPlayer.pause();
            _imgBtnPlay.setImageResource(R.drawable.ic_action_play);
            resetProgress();
            break;

        default:
                break;
    }

// Updating the seek bar's time after every 100 milliseconds
public void updateSeekBar() 
{
    durationHandler.postDelayed(updateSeekBarTime, 100);
}

// Updating the progress of seek bar
private Runnable updateSeekBarTime = new Runnable()
{
    public void run()
    {
        long tDuration = audioPlayer.getDuration();
        long cDuration = audioPlayer.getCurrentPosition();

        lbl_tDuration.setText(mSecToTimer(tDuration));
        lbl_cDuration.setText(mSecToTimer(cDuration));

        int progress = (int) getProgressPercentage(cDuration, tDuration);
        _seekbar.setProgress(progress);
        durationHandler.postDelayed(this, 100);
    }
};

// Converting milliseconds into min:sec format
public String mSecToTimer(long ms)
{
    String finalTimerString = "";
    String secString = "";
    String minString = "";

    // Convert total duration into minutes and seconds
    int min = (int)(ms % (1000*60*60)) / (1000*60);
    int sec = (int) ((ms % (1000*60*60)) % (1000*60) / 1000);

    // Prepending 0 to seconds if it is one digit
    if(sec < 10)
        secString = "0" + sec;
    else
        secString = "" + sec;

    // Prepending 0 to minutes if it is one digit
    if(min < 10)
        minString = "0" + min;
    else
        minString = "" + min;

    finalTimerString = minString + ":" + secString;
    return finalTimerString;
}

// calculating the percentage progress of seek bar
public int getProgressPercentage(long cDuration, long tDuration)
{
    Double percentage = (double) 0;
    long cSeconds = (int) (cDuration / 1000);
    long tSeconds = (int) (tDuration / 1000);

    percentage =(((double)cSeconds)/tSeconds)*100;
    return percentage.intValue();
}

// Converting progress of seek bar into time duration in milliseconds
public int progressToTimer(int progress, int tDuration) 
{
    int cDuration = 0;
    tDuration = (int) (tDuration / 1000);
    cDuration = (int) ((((double)progress) / 100) * tDuration);
    return cDuration * 1000;
}

// Reseting the progress of seek bar when stop button is tapped
public void resetProgress() 
{
    audioPlayer.seekTo(0);
    lbl_cDuration.setText(mSecToTimer(0));
    _seekbar.setProgress(0);
}

我有一个英语音频和一个乌尔都语音频。两者都在数组audioPlayerList 中。用户可以使用单选按钮选择不同的语言。 idx 是变量,它告诉要播放哪个音频文件。 audio_eng 位于索引 0 (idx = 0) 上,audio_urdu 位于索引 1 (idx = 1) 上。音频选为audioPlayer = audioPlayerList[idx]

单选按钮选择代码如下:

rdGrp.setOnCheckedChangeListener(new OnCheckedChangeListener()
    {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) 
        {
            // Find which radio button is selected
            if (audioPlayer!=null)
            {
                if(audioPlayer.isPlaying())
                    audioPlayer.pause();
                _imgBtnPlay.setImageResource(R.drawable.ic_action_play);
                resetProgress();

                if (checkedId == R.id.rdEng) 
                        audioPlayer = audioPlayerList[0];
                else if (checkedId == R.id.rdUrdu)
                        audioPlayer = audioPlayerList[1];
            }
        }
    });

【问题讨论】:

  • 让您的程序根据idx 变量执行这些不同操作的设计目标是什么?这看起来可能会导致您描述的问题。
  • @ChrisStratton 我已经更新了我的问题
  • 您的代码根据idx 的值执行不同的操作似乎是您的问题的根源 - 您只尝试处理两种情况之一的持续时间。这是没有意义的,您需要完全重写该部分,因此行为上的唯一区别是不同语言在程序中的角色所必需的。独立计算准备回调似乎也有风险——真的,你应该从清楚地知道你想让你的程序做什么来重新开始。

标签: android audio mediacontroller


【解决方案1】:

文件“audio_eng”的持续时间可能少于 1 秒。在计算百分比时,您将毫秒转换为秒,从而得到0 总长度。这就是为什么您从一开始就将进度条设置为 100%(实际上,在这种情况下可能会引发异常 - 您检查了吗?)。

在计算percentage 时,尽量不要将xDuration 转换为xSeconds,而是在方法getProgressPercentage 中自行划分持续时间。

我找不到你得到这样结果的其他原因

【讨论】:

  • 我的音频文件总是大于 10 秒。应用程序在播放 audio_eng 时显示正确的经过时间。例如,它显示经过时间:00:21 和总时间:00:00 @CoolSoft
猜你喜欢
  • 1970-01-01
  • 2021-11-05
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2016-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多