5

I have a mp3 file and my application must seek to some selected time of that mp3 file then start playing from there.

I convert my string time by this method to int value

private static int convert(String time) {
    int quoteInd = time.indexOf(":");
    int pointInd = time.indexOf(".");

    int min = Integer.valueOf(time.substring(0, quoteInd));
    int sec = Integer.valueOf(time.substring(++quoteInd, pointInd));
    int mil = Integer.valueOf(time.substring(++pointInd, time.length()));

    return (((min * 60) + sec) * 1000) + mil;
} 

Note: my stings is like this 5:12.201 that means 5 mins and 12 seconds and 201 milliseconds.

I getted these times from MP3 Audio Editor application (it's for windows) and I checked theme with KMPlayer application (it's for windows). And these times was correct on both of them.

But in my app when I seek my MediaPlayer to that time, audio doesn't start from my selected position. (time is correct but sound is different.)


I thought that the MediaPlayer doesn't seek to that time correctly. So I checked current position by calling getCurrentPosition() before playing but returned value and seeked value was same.

I haven't any Idea about It.


Edit:

My problem is NOT time converting.

I convert and seek to there correctly but it play something that not expected in that time.

It means timing in KMPlayer and Android are differents.

My question is Way? and How can is solve it?

golkarm
  • 1,021
  • 1
  • 11
  • 22
  • Is this an CBR or VBR MP3 file (constant or variable bitrate)? – Robert May 17 '16 at 17:27
  • You must respond to suggestions, if you want help for a working answer. What happens if you check current position **after playing**? The logic is to check what time it's playing from **now**, don't care about last position checked before you even start to play. What does `System.out.println`say about value of `getCurrentPosition();`? it should be `312201` if you want to seek to 5mins 12secs & 201 millisecs... Also if loading from internet make sure the 5mins is available (buffered) before seeking to that time. – VC.One May 18 '16 at 13:49
  • PS: I tested your code before & it gave the correct seek value of `312201`. What number are you getting for it to seek to correct time but play wrong audio part? How offset is wrong part, like is it playing audio of 30 seconds ahead / behind the actual required seek time ? – VC.One May 18 '16 at 13:58

2 Answers2

3

You must seek using the seekTo method. This expects miliseconds as time offset. Your offset is how far from the beginning you want to play, for example 1 minute from start can be your offset.

Note: my strings is like this 5:12.201 (Mins : Secs : Millisecs)

If you want to seek to a time like 5:12.201 then use seekTo(312201);

Explained :

1000 ms gives you one second, so 12000 is 12 seconds, and 60000 is one minute.

If you want 5m:12s time then do as :

MyMins = 1000 * 60 * 5; //# 5 mins at 60 secs per minute
MySecs = 1000 * 12; //# 12 secs
MyMilliSecs = 201; //# 201 millisecs
SeekValue = (MyMins + MySecs + MyMilliSecs);
seekTo(SeekValue); //# seeks to 312201 millisecs (is == 5 min & 12 secs & 201 ms)
VC.One
  • 14,790
  • 4
  • 25
  • 57
  • Your answer is just a copy of my question. Please read question before answering. – golkarm May 20 '16 at 10:44
  • How bad is the offset? Is it off by minutes or seconds or just milisecs? When you seek your specific MP3 does it play audio of say 30 seconds ahead or behind your actual required seek time? Is your MP3 made using Variable or Constant Bitrate? Is your test MP3 a **stereo 16-bit 44100 hz (44.1 khz)** file? Reply since these things matter for a working answer – VC.One May 20 '16 at 19:47
1

I usually use this function.

I think It can help to you.

 public static String milliSecondsToTimer(long milliseconds){
    String finalTimerString = "";
    String secondsString = "";

    int hours = (int)( milliseconds / (1000*60*60));
    int minutes = (int)(milliseconds % (1000*60*60)) / (1000*60);
    int seconds = (int) ((milliseconds % (1000*60*60)) % (1000*60) / 1000);
    if(hours > 0){
        finalTimerString = hours + ":";
    }

    if(seconds < 10){
        secondsString = "0" + seconds;
    }else{
        secondsString = "" + seconds;}

    finalTimerString = finalTimerString + minutes + ":" + secondsString;

    return finalTimerString;
}

Good luck :)

Burak iren
  • 338
  • 3
  • 14