Android: как отображать текст за определенные миллисекунды во время воспроизведения мультимедиа (mp3) - PullRequest
3 голосов
/ 24 марта 2011

Я пытаюсь создать караоке-приложение . Я хочу отображать слово или слова, когда наступают определенные миллисекунды.Например:

1148 мс -> печать "Николай"1826 мс -> печать "было"2766 мс -> печать "старше"...*** мс -> дисплей "***"

Вот мой код:

пакет com.example.hellomedia;

import java.io.IOException;импорт android.app.Activity;импорт android.media.MediaPlayer;импорт android.os.Bundle;импорт android.os.Handler;import android.widget.TextView;

открытый класс 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);
        }    
    });


}

}

При запуске этого слова из массива не используетсяраспечатаны.

Я новичок в android dev.Спасибо заранее.:)


Спасибо за все ваши ответы @Matthew Willis, @MarvinLabs и @Bill Mote.Я придумал именно то, что мне было нужно.Мой код выглядит примерно так:

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[] = {
            "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);
        }    
    });


}
}

Ответы [ 2 ]

3 голосов
/ 24 марта 2011

Вам не гарантируется, что ваш обработчик сообщений будет вызываться точно каждую миллисекунду.Вы должны немного расслабиться:

 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);
2 голосов
/ 24 марта 2011

Как насчет использования неравенства для измерения миллисекунд:

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

Маловероятно, что ваша функция будет вызвана, когда позиция воспроизведения точно равна 1148.

Тогда вам нужно будет отслеживать слова, которые вы уже отобразили, чтобы вы не отображали их дважды.

...