Loop buffered video after getting error in videoView android - android

I want to repeat buffered video after getting error in the VideoView
I have play my video with the following code:
public void playVideo() {
if (!isAdded()) {
return;
}
try {
// Get the URL from String VideoURL
Uri video = Uri.parse("http://www.sample-videos.com/video/mp4/480/big_buck_bunny_480p_20mb.mp4");
videoView.setMediaController(new MediaController(
getActivity()));
videoView.setVideoURI(video);
} catch (Exception e) {
ApplicationClass.gLogger.out("Error Happened in initializing ");
e.printStackTrace();
}
videoView.requestFocus();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
videoView.start();
mp.setLooping(true);
}
});
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
//playVideo again;
if (i == MediaPlayer.MEDIA_ERROR_SERVER_DIED || i == MediaPlayer.MEDIA_ERROR_IO || i == MediaPlayer.MEDIA_ERROR_UNKNOWN) {
mediaPlayer.reset();
}
return true;
}
});
}
every thing is ok, but when I lost my connection my video not looping.
on Error listener called with MediaPlayer.MEDIA_ERROR_IO. I want to loop my buffered video.
what I have tried in onError listener?
call playVideo() method again.
use mediaPlayer.seekTo() and mediaPlayer.start().
use videoView.seekTo().
I search a lot in SO and see many links but not worked for me.
as we can't get buffer data from VideoView, I can't save buffer data to a file and read from that.
thanks in advance
// UPDATE
seek not working in videoView because as in source of VideoView mentioned, when we call seek method following method called:
private boolean isInPlaybackState() {
return (mMediaPlayer != null &&
mCurrentState != STATE_ERROR &&
mCurrentState != STATE_IDLE &&
mCurrentState != STATE_PREPARING);
}
as mCurrentState is STATE_ERROR seek not work any more, but i can't figure out how to fix my issue yet.

Maybe it's be helpful:
textureView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
//it,s be called without isInPlaybackState()
mp.seekTo(second);
return false;
}
});
It's just recommendation how bypass calling isInPlaybackState().

Related

Android MediaPlayer Streaming YouTube audio stream unexpected LOUD static

What I'm attempting:
I'm using youtube-dl in a Python Daemon on a remote server to get a URL.
That URL is fed into an Android App into a MediaPlayer instance.
What is happening:
Occasionally and unexpectedly the Media player will BLAST static and play at normal speed, sometimes it will blast static and play at 1.5 times speed.
Here's a video of what happens. HEADPHONE WARNING
YouTube Video
Observations:
If there is static it is for the whole song (it isn't intermittent).
I've taken the URLs it provides and they play fine in a PC browser with no static.
It happens on different phones, and it is not just my particular phone.
It takes longer to start tracks that end up being staticy.
Tracks that are staticy make my progress bar (seconds minutes display) just behave strangely. I've seen it count up and down in the first couple seconds, and there is the 1.5x speed I was talking about.
MediaHTTPConnection throws alot of exceptions that I don't know how to handle.
E/MediaHTTPConnectionEx: disconnecting
E/MediaHTTPConnectionEx: RuntimeException: Unbalanced enter/exit
mConnection.disconnect();
Below is the portion of my Python daemon that returns the URL
ydl_opts = {
'skip_download':True, # We just want to extract the info
'format':'bestaudio',
'forceurl':True,
'ignoreerrors':True,
'youtube_include_dash_manifest':False,
'restrict_filenames':True,
'source_address':'10.1.0.38',#we have to set this to force ipv4
'logger': MyLogger()
}
def ytdl(self, url):
url2 = "https://www.youtube.com/watch?v="+url
ydl.download([url2])
Here's the (basically boilerplate) MediaPlayer
public static Stack<Track> tracks = new Stack<>();
private static MediaPlayer mediaPlayer;
private String mediaFile;
private static int duration = 0;
private AudioManager audioManager;
private Boolean userPause = false;
// Binder given to clients
private final IBinder iBinder = new LocalBinder();
public static final String TAG = "Player";
#Override
public IBinder onBind(Intent intent) {
return iBinder;
}
class LocalBinder extends Binder {
Player getService() {
return Player.this;
}
}
public static void seekTo(int msec){
if(mediaPlayer != null){
mediaPlayer.seekTo(msec);
}
}
//The system calls this method when an activity, requests the service be started
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
boolean success = true;
//An audio file is passed to the service through putExtra();
if(intent.hasExtra("uri")){
mediaFile = intent.getStringExtra("uri");
} else {
stopSelf();
success = false;
}
//Request audio focus
if (!requestAudioFocus()) {
//Could not gain focus
Log.d(TAG, "error requesting audio focus");
stopSelf();
success = false;
}
if (mediaFile != null && !mediaFile.equals("") && success) {
Log.d(TAG, "Media File:" + mediaFile);
success = initMediaPlayer();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
//we cant destroy the player here because the back button fires this
//maybe i can not fire super?
super.onDestroy();
/*if (mediaPlayer != null) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
mediaPlayer.release();
}
removeAudioFocus();*/
}
private boolean initMediaPlayer() {
boolean error = false;
//one time setup
if(mediaPlayer == null) {
mediaPlayer = new MediaPlayer();
//setup listeners
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnSeekCompleteListener(this);
mediaPlayer.setOnInfoListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
//Reset so that the MediaPlayer is not pointing to another data source
mediaPlayer.reset();
try {
Log.d(TAG, "setDataSource");
mediaPlayer.setDataSource(mediaFile);
} catch (IOException e) {
Log.e(TAG,"setDataSource error:"+e);
error = true;
}
try {
Log.d(TAG, "prepare");
mediaPlayer.prepare();
} catch (IOException e) {
Log.d(TAG, "prepare error");
e.printStackTrace();
error = true;
}
return error;
}
#Override
public void onPrepared(MediaPlayer mp) {
//Invoked when the media source is ready for playback.
Log.d(TAG, "onPrepared");
mp.start();
duration = mp.getDuration();
}
#Override
public void onCompletion(MediaPlayer mp) {
//Invoked when playback of a media source has completed.
removeAudioFocus();
mp.stop();
mp.reset();
}
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
//Invoked to communicate some info.
return false;
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
//Invoked indicating buffering status of
//a media resource being streamed over the network.
if(percent%25==0)
Log.d(TAG, "buffering:"+percent);
}
#Override
public void onSeekComplete(MediaPlayer mp) {
//Invoked indicating the completion of a seek operation.
Log.d(TAG, "onSeekComplete() current pos : " + mp.getCurrentPosition());
SystemClock.sleep(200);
start();
}
//Handle errors
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
//Invoked when there has been an error during an asynchronous operation
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Log.e(TAG, "MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + extra);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.e(TAG, "MEDIA ERROR SERVER DIED " + extra);
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.e(TAG, "MEDIA ERROR UNKNOWN " + extra);
//NowPlaying.error = true;
break;
default:
Log.e(TAG, what + "," + extra);
break;
}
PlayerActivity.error = true;
return false;
}
#Override
public void onAudioFocusChange(int focusState) {
//Invoked when the audio focus of the system is updated.
switch (focusState) {
case AudioManager.AUDIOFOCUS_GAIN:
// resume playback
mediaPlayer.setVolume(1.0f, 1.0f);
if(!mediaPlayer.isPlaying()
&& !userPause) {
pause(false);
}
break;
case AudioManager.AUDIOFOCUS_LOSS:
// Lost focus for an unbounded amount of time: stop playback and release media player
if (mediaPlayer.isPlaying()) mediaPlayer.pause();
removeAudioFocus();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
// Lost focus for a short time, but we have to stop
// playback. We don't release the media player because playback
// is likely to resume
if (mediaPlayer.isPlaying()) mediaPlayer.pause();
break;
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// Lost focus for a short time, but it's ok to keep playing
// at an attenuated level
if (mediaPlayer.isPlaying()) mediaPlayer.setVolume(0.1f, 0.1f);
break;
}
}
private boolean requestAudioFocus() {
int result = 0;
if(audioManager == null) audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
if (audioManager != null) {
result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}
Log.d(TAG, "requestAudioFocus:"+result);
return result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
//Could not gain focus
}
private void removeAudioFocus() {
audioManager.abandonAudioFocus(this);
}
boolean isPlaying() {
if(mediaPlayer != null)
return mediaPlayer.isPlaying();
return false;
}
//pause(true) == pause
//pause(false) == play
//this is used by the system
void pause(Boolean state){
//pause
if (state) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
} else {
if (!mediaPlayer.isPlaying()) {
start();
}
}
}
//this is a pause toggle that is only triggered by the pause/play button
boolean pause() {
if (mediaPlayer.isPlaying()){
userPause = true;
mediaPlayer.pause();
} else {
userPause = false;
start();
}
return !mediaPlayer.isPlaying();
}
void start(){
mediaPlayer.start();
}
int getCurrentPosition(){
if(mediaPlayer != null)
return mediaPlayer.getCurrentPosition();
return 0;
}
int getDuration(){
return duration;
}
}
I feel like someone else is going to have this problem so I'm going to post my solution.
So I noticed a mime type error popped up for every track. The error still shows up now that I've fixed this problem but the loud static has stopped.
Here is the error that started the wheels turning:
E/MediaHTTPConnectionEx: getMIMEType
[seekToEx] offset:0/mCurrentOffset:-1
I noticed some of the URLs youtube-dl was giving me for the webm didn't have a mime type specified in the URL.
Here is an example:
...O8c2&mime=&pl=...
But all of the m4a streams had a mime type in the URL
...70F61&mime=audio%2Fmp4&itag=140&key...
So I think that while my solution isn't the best solution, it's the easiest. Since ALL the m4a streams had a mime specified I just limited myself to those streams.
The rub is this:
I'm pretty sure that if I just checked the URL for a specified mime field I could still play most webm files. The only ones that were failing (staticy) were URLs that did not have that field.
My solution:
Python only pulls m4a files:
...
'format':'bestaudio[ext=m4a]',
...
Android now passes hard coded headers:
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "audio/mp4"); // change content type if necessary
Uri uri = Uri.parse(mediaFile);
Log.d(TAG, "getMimeType="+getMimeType(uri));//this is ALWAYS null
mediaPlayer.setDataSource(getApplicationContext(), uri, headers);

Audio Playing But Video not Showing in VideoView Android (Black Screen in Low Internet)

I am Working on Video Streaming in Android. when I want to play video in Low Internet Speed video is not appear in the VideoView show black Screen but Audio is playing fine. i have see these links link1 and link2 . But these link couldn't help me. Here is my code snapshot:-
private void playvideo(String url){
final MediaController mediacontroller;
try {
mediacontroller = new MediaController(MainActivity.this);
mediacontroller.setAnchorView(videoView);
final Uri video = Uri.parse(url);
videoView.setMediaController(mediacontroller);
videoView.setVideoURI(video);
videoView.requestFocus();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
// Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
mp.start();
mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mediaPlayer, int what, int extra) {
if (extra == MediaPlayer.MEDIA_ERROR_SERVER_DIED
|| extra == MediaPlayer.MEDIA_ERROR_MALFORMED) {
Log.e(TAG , "MEDIA_ERROR_SERVER_DIED && MEDIA_ERROR_MALFORMED");
Toast.makeText(MainActivity.this , "Server Died or Malformed" , Toast.LENGTH_LONG).show();
return true;
} else if (extra == MediaPlayer.MEDIA_ERROR_IO) {
Log.e(TAG , "MediaPlayer.MEDIA_ERROR_IO");
Toast.makeText(MainActivity.this , "Media Error IO" , Toast.LENGTH_LONG).show();
return true;
}else if (extra == MediaPlayer.MEDIA_ERROR_UNKNOWN){
Log.e(TAG , ".MEDIA_ERROR_UNKNOWN");
Toast.makeText(MainActivity.this , "MEDIA ERROR UNKNOWN" , Toast.LENGTH_LONG).show();
return true;
}
return false;
}
});
mp.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
#Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int percentage) {
Log.e(TAG , "onBufferingUpdate :- " + percentage);
}
});
progressBar.setVisibility(View.GONE);
videoView.start();
}
});
} catch (Exception e) {
Log.e("Error", e.getMessage());
progressBar.setVisibility(View.GONE);
Toast.makeText(getApplicationContext() ,"URL is Wrong Test with other URL" , Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
because Audio and Video both are different Streams so in Low Internet somehow it able to download the audio stream but not a video stream, is it ?? so in this case, it is possible to show a message to the user like "you have Low Internet Try Again" and not to play Audio ??
thanks
Try to use Exoplayer which is an alternative to Android’s MediaPlayer API for playing audio and video both locally and over the Internet.
https://github.com/google/ExoPlayer
I recommend you to use SurfaceView.
surfaceView = (SurfavceView) findView.....;
holder = surfaceView.getHolder();
holder.addCallback(this); // implement SurfaceHolder.Callback methods
Then in surfaceCreated method:
mediaPlayer.setDisplay(holder);
mediaPlayer.setDataSource(mVideoUrl);
mediaPlayer.prepareAsync();
You also can use https://github.com/anthorlop/EasyExoPlayer
It use ExoPlayer for Android SDK >= 16 and MediaPlayer for Android < 16.
I hope it works for you.

videoView.setOnPreparedListener, videoView.setOnCompletionListener and videoView.setOnErrorListener not getting called

Here is my code snippet where I want to play a video coming from server
private void PlayVideo() {
try {
getWindow().setFormat(PixelFormat.TRANSLUCENT);
MediaController mediaController = new MediaController(VideoActivity.this);
mediaController.setAnchorView(videoView);
Uri video = Uri.parse(videoPath);
videoView.setMediaController(mediaController);
videoView.setVideoURI(video);
videoView.requestFocus();
videoPlayer.removeAllViews();
videoPlayer.setVisibility(View.GONE);
videoView.setVisibility(View.VISIBLE);
videoView.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
dismissProgressDialog();
videoView.bringToFront();
videoView.setFocusable(true);
videoView.start();
contentStarted = true;
}
});
videoView.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
contentStarted = false;
}
});
videoView.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
dismissProgressDialog();
Intent in = new Intent();
setResult(1, in);
finish();
return false;
}
});
} catch (Exception e) {
dismissProgressDialog();
finish();
}
}
The ProgressDialog is dismissed only in videoView.setOnPreparedListener and videoView.setOnErrorListener. But the ProgressDialog is not getting dismissed and video is not getting played. I tried to put Logs and see, Logs are printed upto just before videoView.setOnPreparedListener and after that no Logs are displayed. Listeners are not getting registered I guess.
Any help is appreciated.
Thanks in advance.
EDIT:
'M trying to stream a live video, if video is availbale it should go to videoView.setOnPreparedListener and should play the video. If Live is not available(i.e, Video will be live after some time) then it should go to videoView.setOnErrorListener and return to previous Activity with result "1"
and
Video is streamed over RTSP
After a lot of research and with the help of Preethi Rao I got to know that the fault was in the URL.
The URL might have the video (if it is time for Live Video) and might not have video (if Live Video will be streaming after some time). If I'm trying to stream video when Live Video is not available then the Listeners are not getting fired. If Live Video is availbale, Listeners are getting fired. So, videoView.setOnPreparedListener and videoView.setOnErrorListener are not getting attached.
I wrote a handler to run for 60 seconds and if no Listeners are attached I'm just returning to previous Activity.
Here's the code:
private void PlayVideo() {
try {
isListenerAttached = false;
getWindow().setFormat(PixelFormat.TRANSLUCENT);
MediaController mediaController = new MediaController(VideoActivity.this);
mediaController.setAnchorView(videoView);
Uri video = Uri.parse(videoPath);
videoView.setMediaController(mediaController);
videoView.setVideoURI(video);
videoView.requestFocus();
videoPlayer.removeAllViews();
videoPlayer.setVisibility(View.GONE);
videoView.setVisibility(View.VISIBLE);
// Using this Handler to revert to previous Activity when the Video View is not attached to Listeners
// As the Buffering Video dialog doesn't get dismissed if Video View is not attached to Listeners
runOnUiThread(new Runnable() {
#Override
public void run() {
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
if(!isListenerAttached){
dismissProgressDialog();
Intent in = new Intent();
setResult(1, in);
finish();
}
}
}, WAIT_TIME);
}
});
videoView.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
isListenerAttached = true;
dismissProgressDialog();
videoView.bringToFront();
videoView.setFocusable(true);
videoView.start();
contentStarted = true;
}
});
videoView.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
contentStarted = false;
}
});
videoView.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
isListenerAttached = true;
dismissProgressDialog();
Intent in = new Intent();
setResult(1, in);
finish();
return false;
}
});
} catch (Exception e) {
dismissProgressDialog();
finish();
}
}

How can I know if the MediaPlayer is in Stopped state?

I am building an app which plays several videos, and I have two different user scenarios :
Scenario 1. While video 'A' is playing, if user clicks next button, then it stops and play the next video 'B'.
Scenario 2. Play video 'A', and if it's done, user clicks next button and it plays video 'B'.
For the first scenario, I used mediaPlayer.isPlaying() method to detect if it is in Started state and it works fine. However, if I use the same code for the second scenario, isPlaying() throws IllegalStateException.
Here's my code for playing videos :
private void playVideos(SurfaceHolder holder) {
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDisplay(holder);
Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + video_files[mCounter]);
mediaPlayer.setDataSource(this, uri);
mediaPlayer.prepare();
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (mCounter <= 8) {
onVideoCompletion(mediaPlayer);
} else {
mediaPlayer.stop();
mediaPlayer.release();
}
}
});
} catch (IOException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalStateException e) {
}
}
Also, here's my button listener to play next video :
nextBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(mediaPlayer != null) {
if(mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
mCounter += 1;
if (mCounter <= 8) {
playVideos(holder);
}
}
});
One way that I tried to hack this issue was using a boolean variable instead of isPlaying() method. For example,
boolean mIsPlaying = false;
...
// in button listener
if(mIsPlaying) {
mediaPlayer.stop();
mediaPlayer.release();
}
...
// in playVideos() function
mediaPlayer.start();
mIsPlaying = true;
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (mCounter <= 8) {
onVideoCompletion(mediaPlayer);
} else {
mediaPlayer.stop();
mediaPlayer.release();
}
}
});
That works for my both of scenario, but I'm not sure if it's the correct way to do it. Isn't there any way to detect whether mediaPlayer is in Stopped state?
I took a look at Google's Documentation which you can find here. You can only know if the player isPlaying(); or isLooping(); ... So no, there is not an "easy" or "short" way to achieve what you want. Hope it helped.

is it possible to display video information from an rtsp stream in an android app UI

I have managed to get a working video player that can stream rtsp links, however im not sure how to display the videos current time position in the UI, i have used the getDuration and getCurrentPosition calls, stored this information in a string and tried to display it in the UI but it doesnt seem to work
**in main.xml:**
TextView android:id="#+id/player"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="1px"
android:text="#string/cpos"
/>
**in strings.xml:**
string name="cpos">"" /string>
**in Player.java**
private void playVideo(String url) {
try {
media.setEnabled(false);
if (player == null) {
player = new MediaPlayer();
player.setScreenOnWhilePlaying(true);
} else {
player.stop();
player.reset();
}
player.setDataSource(url);
player.getCurrentPosition();
player.setDisplay(holder);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnPreparedListener(this);
player.prepareAsync();
player.setOnBufferingUpdateListener(this);
player.setOnCompletionListener(this);
} catch (Throwable t) {
Log.e(TAG, "Exception in media prep", t);
goBlooey(t);
try {
try {
player.prepare();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.v(TAG, "Duration: ===> " + player.getDuration());
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private Runnable onEverySecond = new Runnable() {
public void run() {
if (lastActionTime > 0
&& SystemClock.elapsedRealtime() - lastActionTime > 3000) {
clearPanels(false);
}
if (player != null) {
timeline.setProgress(player.getCurrentPosition());
//stores getCurrentPosition as a string
cpos = String.valueOf(player.getCurrentPosition());
System.out.print(cpos);
}
if (player != null) {
timeline.setProgress(player.getDuration());
//stores getDuration as a string
cdur = String.valueOf(player.getDuration());
System.out.print(cdur);
}
if (!isPaused) {
surface.postDelayed(onEverySecond, 1000);
}
}
};
Your code snippet looks significantly like my vidtry sample. getCurrentPosition() and getDuration() works for HTTP streaming, such as for use in updating the progress bar.
I have not tried vidtry with an RTSP video stream, mostly because I don't know of any.
Check the SDP response from the server to ensure that it is sending the duration in the response (live streams don't have a recognizable time and that may cause the client to not provide this information.)
E.g. a live feed will look like:
a=range:npt=0-
Whereas a VoD clip should look like:
a=range:npt=0-399.1680
If getCurrentPosition() doesn't work, but you know the Duration (either getDuration() works or you have an alternate way of getting this information; you could calculate it by watching the buffering events and tracking this your self. Your approach is the more desirable approach than this one.
If I got you right, you want to show in a TextView elapsed time e.g. hh:mm:ss?
If so, I'll give you a little walkthrough on how to do that.
private TextView mElapsedTimeText;
private VideoView mVideoView;
private Thread mThread;
#Override
public void onCreate(Bundle savedInstanceState) {
/* here goes your code */
// let's assume that your IDs are elapsedId and videoId
mElapsedTimeText = (TextView) findViewById(R.id.elapsedId);
mVideoView = (VideoView) findViewById(R.id.videoId);
mThread = new Thread() {
#Override
public void run() {
mElapsedTime.setText(getNiceString());
mVideoView.postDelayed(mThread, 1000);
}
}
/* here goes your code */
}
public String getNiceString() {
String result = "";
int position = mVideoView.getCurrentPosition();
/* here goes your code */
//result is hh:mm:ss formatted string
return result;
}
#Override
public void onPrepared(MediaPlayer mp) {
/* here goes your code */
// you have to trigger the process somewhere
mVideoView.postDelayed(mThread, 1000);
/* here goes your code */
}
And one more thing I forgot to mention. In order to make this work your activity class has to implement the OnPreparedListener interface.
I hope you or someone else will find this post useful.
Best regards,
Igor

Categories

Resources