Android:如何在播放媒体(mp3)时在特定毫秒内显示文本
我正在尝试做一个类似卡拉 OK 的应用程序。 我想在某一毫秒到来时显示一个或多个单词。例如:
1148毫秒->打印“尼古拉斯”
1826 毫秒 ->打印“是”
2766 毫秒 ->打印“旧”
...
***女士->显示“***”
这是我的代码:
package com.example.hellomedia;
导入java.io.IOException; 导入 android.app.Activity; 导入 android.media.MediaPlayer; 导入 android.os.Bundle; 导入 android.os.Handler; 导入 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);
}
});
}
}
当我运行此命令时,不会打印数组中的任何单词。
我是 Android 开发新手。非常感谢。 :)
感谢您的所有回复@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);
}
});
}
}
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[] = {
"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);
}
});
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您无法保证您的消息处理程序将在每毫秒被准确调用。你必须给它一些松懈:
You are not guaranted that your message handler will be called exactly each millisecond. You must give it some slack:
使用不等式来测量毫秒怎么样:
当播放位置正好是 1148 时,您的函数不太可能被调用。
那么您将需要跟踪已经显示的单词,以便不显示它们两次。
What about using an inequality to measure the milliseconds:
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.