videoview.getDuration() returns -1 - android

i am trying to develop a android app for playing a video from raw folder. am using custom control options. the getduration() returns -1 so i cant set max value to my seekbar. here is my code
private MediaController mediaController;
private VideoView videoView;
public TextView duration;
private int timeElapsed=0,finalTime=0;
private int forwardTime=2000, backwardTime=2000;
private SeekBar seekBar;
private Handler durationHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialize();
}
public void initialize()
{
videoView =(VideoView)findViewById(R.id.videoView1);
mediaController= new MediaController(this);
mediaController.setAnchorView(videoView);
String
uri1="android.resource://"+getPackageName()+"/"+R.raw.materialdesign;
Uri uri = Uri.parse(uri1);
videoView.setMediaController(null);
videoView.setVideoPath("android.resource://" + getPackageName() + "/" +
R.raw.materialdesign);
Log.e("finalTime", "" + finalTime);
finalTime = videoView.getDuration();
Log.e("finalTime", ""+finalTime);
Log.e("finalTime", ""+videoView.getDuration());
duration = (TextView) findViewById(R.id.songDuration);
seekBar = (SeekBar) findViewById(R.id.seekBar);
seekBar.setMax(finalTime);
seekBar.setClickable(false);
videoView.requestFocus();
}

In case you haven't found a solution, VideoView.getDuration() will return -1 if the video is not in playback state. The video is not in playback state until it has been prepared. So calling VideoView.getDuration() directly after setting the URI does not guarantee that the video has been prepared.
I found this by looking at the source of VideoView:
#Override
public int getDuration() {
if (isInPlaybackState()) {
return mMediaPlayer.getDuration();
}
return -1;
}
The solution is to set an OnPreparedListener to your VideoView, and obtain the duration once the video is prepared. You can then use VideoView.getDuration() or MediaPlayer.getDuration(), which are nearly identical.
Solution:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
int duration = mp.getDuration();
int videoDuration = videoView.getDuration();
Log.d(TAG, String.format("onPrepared: duration=%d, videoDuration=%d", duration,
videoDuration);
}
seekBar.setMax(videoDuration);
});

Related

How to check a variable in background to do something when it reaches to a value?

I have a simple VideoView that plays a video:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final VideoView videoView=findViewById(R.id.videoView);
videoView.setVideoURI(Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.video));
MediaController mediaController=new MediaController(this);
videoView.setMediaController(mediaController);
videoView.start();
TextView textView = findViewById(R.id.textView);
}
}
By using videoView.getCurrentPosition(), I can get the current elapsed milliseconds of the playing video. Now, I need to continuously check this value in background, and when it reaches to some (for example 10000), do something (updating the TextView's text).
It's important for me to do this is background so that doesn't disturb the video playback.
Is it possible?
You can listen to the MediaController's SeekBar events, by overriding its 3 methods, of course you' re interested in 1 of them onProgressChanged():
final VideoView videoView=findViewById(R.id.videoView);
videoView.setVideoURI(Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.video));
final MediaController mediaController=new MediaController(this);
videoView.setMediaController(mediaController);
final TextView textView = findViewById(R.id.textView);
textView.setText("0");
int topContainerId = getResources().getIdentifier("mediacontroller_progress","id", "android");
final SeekBar seekbar = (SeekBar) mediaController.findViewById(topContainerId);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
int currentValue = Integer.parseInt(textView.getText().toString());
int newValue = progress / 1000;
if (newValue != currentValue) {
textView.setText(String.valueOf(newValue));
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
videoView.start();

Can i loop multiple videos stored on raw folder in videoview?

What im trying to achieve is to play multiple videos stored on raw folder to be played on loop and sequentially one after the other?
I can play only one in loop in videoview but cant access other ones.
Thanks in advance.
Here is my videoview.
private VideoView myVideo1;
String path = "http://192.168.0.22/output/files/video/";
Uri uri=Uri.parse(path);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
setContentView(R.layout.activity_main);
myVideo1=(VideoView)findViewById(R.id.myvideoview);
myVideo1.setVideoURI(uri);
myVideo1.start();
myVideo1.requestFocus();
myVideo1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.setLooping(true);
}
});
}
To play multiple videos located in raw, try the following approach:
(NOTE: take care of the index and your video files naming. This example assumes your videos are named video1, video2..... videoX)
private final int COUNT = 3;
private int index = 1;
private VideoView myVideo1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().setFormat(PixelFormat.TRANSLUCENT);
setContentView(R.layout.activity_main);
myVideo1 = (VideoView) findViewById(R.id.myvideoview);
myVideo1.requestFocus();
myVideo1.setVideoURI(getPath(index));
index++;
myVideo1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
myVideo1.start();
}
});
myVideo1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
//videos count +1 since we started with 1
if (index == COUNT + 1) index = 1;
myVideo1.setVideoURI(getPath(index));
index++;
}
});
}
private Uri getPath(int id) {
return Uri.parse("android.resource://" + getPackageName() + "/raw/video" + id);
}
Getting resources from raw explained: android.resource:// is a constant part of the path, getPackageName() points to your application, /raw/ tells the system where to look for the file, video is the constant naming prefix of your files and the id is a dynamic suffix of your file names.
VideoView uses the MediaPlayer for playing videos, here's an overview of its states (taken from the official docs) for better understanding:

How to start video view when buffering reaches percentage that i want (20%) android

I want to stream video from url.When buffer reached 20% i want to start video in the same moment.Here is my code...
public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final VideoView vidView = (VideoView) findViewById(R.id.myVideo);
MediaController vidControl = new MediaController(this);
vidControl.setAnchorView(vidView);
vidView.setMediaController(vidControl);
String vidAddress = "http://d38e3g3vk5nrvg.cloudfront.net/1452268197713.mp4";
Uri vidUri = Uri.parse(vidAddress);
vidView.setVideoURI(vidUri);
vidView.start();
vidView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mp.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
#Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int i) {
Log.d(TAG, "onBufferingUpdate: " + i);
if (i >= 20) {
Log.d(TAG, "onBufferingUpdate: >= 20");
vidView.start();
}
}
});
}
});
}
The problem is when buffering reach 20% video didn't start ... start when reached 50% every time... but this is too much waiting for users when video is bigger.Thank you in advance!

Android setNextMediaPlayer() API for MediaPlayer is not playing next video

I have a simple activity which contains one instance of a VideoView and a reference to its' MediaPlayer. My goal was to use the setNextMediaPlayer() api from the MediaPlayer object in order to minimize the switching time between 2 videos.
In the below code, the 1st video plays well. When the 1st video completes, the 2nd video's audio begins to play in the background, but only the last frame of the 1st video is shown.
Do you know what the problem is? Why isn't the 2nd video's video displaying?
private VideoView player1;
private MediaPlayer mediaPlayer1;
public static final String URL_1 = "https://example.com/video1.mp4";
public static final String URL_2 = "https://example.com/video2.mp4";
public static final String TAG = "PrebufferingActivity";
public boolean FIRST_TIME = true;
public int count = 0;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_prebuffering);
player1 = (VideoView) findViewById(R.id.videoPlayer1);
player1.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer1 = mp;
if(FIRST_TIME == true)
{
mediaPlayer1.start();
player1.requestFocus();
FIRST_TIME = false;
}
}
});
player1.setOnInfoListener(new OnInfoListener(){
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra)
{
if(what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
{
count++;
if(count % 2 != 0)
{
Log.d(TAG, "Odd count (" + count + ") Prebuffering URL_2");
MediaPlayer myMediaPlayer = MediaPlayer.create(PrebufferingActivity.this, Uri.parse(URL_2));
mp.setNextMediaPlayer(myMediaPlayer);
}
else
{
Log.d(TAG, "Even count (" + count + ") Prebuffering URL_1");
MediaPlayer myMediaPlayer = MediaPlayer.create(PrebufferingActivity.this, Uri.parse(URL_1));
mp.setNextMediaPlayer(myMediaPlayer);
}
}
return false;
}
});
player1.setOnCompletionListener(new OnCompletionListener(){
#Override
public void onCompletion(MediaPlayer mp) {
}
});
// Player 1
player1.setMediaController(new MediaController(this));
player1.setVideoURI(Uri.parse(URL_1));
}
In your example you create new MediaPlayer, but VideoView knows nothing about and can't control it. It wouldn't work properly.
If you need some specific functions probably you need to build your analog of VideoView, that would use MediaPlayer.
Regarding playing 2nd video by using setNextMediaPlayer() you can find some hints here:
https://stackoverflow.com/a/28465846/755313

Android: VideoView can't play video

im trying to get a basic video player working for an android application im working on but whenever i try to play the video i get an error saying "cant play video". Im certain the video is in supported formats and ive tried converting it between several of the supported formats on top of that so i assume its an issue with my code:
public class VideoActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_layout);
VideoView videoView = (VideoView)findViewById(R.id.VideoView1);
MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.setVideoPath("TravelAppTopic4/res/raw/canadavid.mp4");
videoView.start();
}
thanks in advance for any help
edit:im testing on both a virtual device and an S3 to the same result.
public class VideoScreen extends Activity{
private MediaController controller;
Context _ctx = VideoScreen.this;
private Thread thread;
ProgressBar progressBar = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.phone_video_screen);
progressBar = (ProgressBar) findViewById(R.id.progressbar);
VideoView video = (VideoView) findViewById(R.id.videoView1);
controller = new MediaController(VideoScreen.this);
video.setMediaController(controller);
video.setVideoPath(_url);
video.requestFocus();
video.start();
progressBar.setVisibility(View.VISIBLE);
video.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.start();
progressBar.setVisibility(View.GONE);
mp.setOnVideoSizeChangedListener(new OnVideoSizeChangedListener() {
#Override
public void onVideoSizeChanged(MediaPlayer mp, int arg1,
int arg2) {
progressBar.setVisibility(View.GONE);
mp.start();
}
});
}
});
}
}
try
videoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw. canadavid));

Categories

Resources