开发者

Android: How to display text in certain milliseconds while media (mp3) is playing

开发者 https://www.devze.com 2023-02-19 06:11 出处:网络
I\'m trying to do a karaoke-like application. I want to display a word or words when a certain milliseconds come. For example:

I'm trying to do a karaoke-like application. I want to display a word or words when a certain milliseconds come. For example:

1148 ms -> print "Nicholas "

1826 ms -> print "was "

2766 ms -> print "older "

...

*** ms -> display "*** "

Here's my code:

package com.example.hellomedia;

import java.io.IOException; import android.app.Activity; import android.media.MediaPlayer; import android.os.Bundle; import android.os.Handler; import android.widget.TextView;

public class HelloMedia extends Activity {

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final Handler mHandler = new Handler();
    final TextView tv = new TextView(this);

    tv.setText("Playing... ");
    setContentView(tv);

    final MediaPlayer mPlayer = MediaPlayer.create(this, R.raw.nicholas);




    final String words[] = {
            "Nicholas ",// 0
            "was ", // 1
            "older ",// 2
            "than ",// 3
            "sin ",// 4
            "and ",// 5
            "his ",// 6
            "beard ",// 7
            "could ",// 8
            "go ",// 9
            "no ",// 10
            "whiter. "// 11
    };



    try {
        mPlayer.prepare();
    } catch (IllegalStateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    mPlayer.start();

    mHandler.post(new Runnable(){
        public void run(){ 

            //tv.setText(" [ " + mPlayer.getCurrentPosition() + " ] ");
            if( mPlayer.getCurrentPosition() == 1148 ){//0
                tv.append(words[0]);
            }
            if( mPlayer.getCurrentPosition() == 1826 ){//1
                tv.append(words[1]);
            }
            if( mPlayer.getCurrentPosition() == 2766 ){//2
                tv.append(words[2]);
            }
            mHandler.postDelayed(this, 1);
        }    
    });


}

}

When I run this, no word(s) from the array is being printed.

I'm new to android dev. Many thanks in advance. :)


Thanks for all your responses @Matthew Willis, @MarvinLabs, and @Bill Mote. I came up exactly with what I needed. My code goes something like this:

package com.example.hellomedia;

import java.io.IOException;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.widget.TextView;

public class HelloMedia extends Activity {

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final Handler mHandler = new Handler();
    final TextView tv = new TextView(this);

    tv.setText("Playing1... ");
    setContentView(tv);

    final MediaPlayer mPlayer = MediaPlayer.create(this, R.raw.nicholas);

    try {
        mPlayer.prepare();
    } catch (IllegalStateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    mPlayer.start();


    final String words开发者_JS百科[] = {
            "Nicholas ",// 0
            "was ", // 1
            "older ",// 2
            "than ",// 3
            "sin ",// 4
            "and ",// 5
            "his ",// 6
            "beard ",// 7
            "could ",// 8
            "go ",// 9
            "no ",// 10
            "whiter. "// 11
    };

    final long startEndTime[][]={
            {   //start time
                1148,// 0,0
                1826, // 0,1
                2766,// 0,2
                3079,// 0,3
                3549,// 0,4
                4540,// 0,5
                4697,// 0,6
                4801,// 0,7
                5114,// 0,8
                5323,// 0,9
                5532,// 0,10
                5845// 0,11
            },
            {   //end time
                1357,// 1,0
                2192, // 1,1
                3027,// 1,2
                3183,// 1,3
                3966,// 1,4
                4645,// 1,5
                4749,// 1,6
                4958,// 1,7
                5219,// 1,8
                5427,// 1,9
                5740,// 1,10
                6210// 1,11
            }

        };

    mHandler.post(new Runnable(){

        public void run(){ 
            final long currentPos = mPlayer.getCurrentPosition();

            int x = 0;

            while( x < 12){
                if( currentPos > startEndTime[0][x] && currentPos < startEndTime[1][x] ){//0
                    tv.append(words[x]);
                    words[x]="";
                }
                x++;
            }

            mHandler.postDelayed(this, 1);
        }    
    });


}
}


You are not guaranted that your message handler will be called exactly each millisecond. You must give it some slack:

 mHandler = new Handler() {
        public void handleMessage(Message msg){     
            final long currentPos = mPlayer.getCurrentPosition();

            if (currentPos > 1100 && currentPos < 1300) {
                tv.append(words[0]);
            } else if (currentPos > 1300 && currentPos < 1400) {
                tv.append(words[1]);
            } 

            mHandler.sendEmptyMessageDelayed(0, 1);
        }
    };


mHandler.sendEmptyMessage(0);


What about using an inequality to measure the milliseconds:

if (mPlayer.getCurrentPosition() > 1148) {
    ...

It's very unlikely that your function will be called when the playback position is exactly 1148.

Then you will need to keep track of the words that you have already displayed so that you don't display them twice.

0

精彩评论

暂无评论...
验证码 换一张
取 消