Native Android Media player does not invoke onCompletion method after the video has ran it's duration.
I have an Activity that plays a single video or a list of videos (m3u8 file). Video plays file as it should, I can use the media controller as well, however, when the video runs out, after a few seconds he starts a loop. onCompletion method doesn't activate unless the user clicks (or double taps) the fast forward option on media controler.
Is there a way to make the onComplete method activate automatically when the video runs out? (I've tried using the listener, doesn't work). Pointing out what I did wrong also works.
Here is the activity that handles video playing:
public class VideoActivity extends ActionBarActivity implements MediaPlayer.OnCompletionListener {
private static final String TAG = VideoActivity.class.getSimpleName();
private VideoView mVideoViewStream1;
ProgressDialog mDialog;
private String mURL;
private ChannelPlaylist mChannelPlaylist;
private int mIndex;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video);
// Validate internet connection
if (!Util.isDeviceConnected(this)) {
FragmentManager fm = getSupportFragmentManager();
PopUpErrorFragment popupError = PopUpErrorFragment.newInstance(getString(R.string.errorInternetConnection));
popupError.show(fm, PopUpErrorFragment.TAG);
finish();
}
// Assign controls to their variable representations
mVideoViewStream1 = (VideoView) findViewById(R.id.vvVideo);
// Retrieve bundle data
Intent i = getIntent();
Bundle bundle = i.getExtras();
ChannelPlaylist channelPlaylist = bundle.getParcelable(KeyHelper.BUNDLE_CHANNEL_PLAYLIST);
if (channelPlaylist != null) {
this.mChannelPlaylist = channelPlaylist;
if (bundle.containsKey("index") && mIndex == 0) {
this.mIndex = bundle.getInt("index");
} else {
if (this.mIndex == 0) {
this.mIndex = this.mChannelPlaylist.getIndex();
}
}
this.mURL = this.mChannelPlaylist.getSchedule().get(mIndex).getStream_url();
} else {
this.mURL = bundle.getString("url");
}
progressDialog();
standardAndroidPlayer();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.video, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/***************************** CLASS METHODS **************************************************/
/**
* Dismissess the dialog
*/
private void dismissDialog() {
if (this.mDialog != null) {
mDialog.dismiss();
}
}
/**
* Standard android player
*/
private void standardAndroidPlayer() {
try {
// Start the MediaController
MediaController mediacontroller = new MediaController(this);
mediacontroller.setAnchorView(mVideoViewStream1);
// Get the URL from String VideoURL
mVideoViewStream1.setMediaController(mediacontroller);
// Set media player completion listener
mVideoViewStream1.setOnCompletionListener(this);
mVideoViewStream1.setVideoURI(Uri.parse(this.mURL));
mVideoViewStream1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
//Log.i(TAG, "Duration = " + mVideoViewStream1.getDuration());
if (mp.isLooping()) mp.setLooping(false);
}
});
mVideoViewStream1.requestFocus();
mVideoViewStream1.start();
} catch (Exception e) {
dismissDialog();
Log.e(TAG, "Error" + e.getMessage());
e.printStackTrace();
}
dismissDialog();
}
#Override
public void onCompletion(MediaPlayer mp) {
this.mIndex++;
if (this.mIndex < mChannelPlaylist.getSchedule().size()) {
this.mURL = this.mChannelPlaylist.getSchedule().get(this.mIndex).getStream_url();
standardAndroidPlayer();
} else {
finish();
}
}
/**
* Creates a progress dialog
*/
private void progressDialog() {
// Create a progressbar
mDialog = new ProgressDialog(VideoActivity.this);
// Set progressbar title
mDialog.setTitle("Android Video Streaming Tutorial");
// Set progressbar message
mDialog.setMessage("Buffering...");
mDialog.setIndeterminate(false);
mDialog.setCancelable(false);
// Show progressbar
mDialog.show();
}
}
Edited:
Ok, for some strange reason, on mobile phone the method doesn't fire off, however when used on tablet, it does. I wasn't able to reproduce the effect on tablet and didn't have any success on the phone either. Does it have something to do with the versions of android? Since I didn't get any warnings about compatibility when writing the listener, I didn't think much about it.
Try this.
mVideoViewStream1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
finish();
}
});
Related
OK -- I am using Android Studio 3.0 and YouTube API version 3 in my project.
I have added the library/jar files to the project (via this link).
The project compiles.
Here is the weird thing I cannot figure out: When I run the app and select a video, the app says "An error occurred while initializing YouTube player" This happens on device and emulator.
I looked at the IDE, I looked at the logcat and all I find is this error message on the IDE itself:
And I see this in the upper part of the IDE as well:
What is it that I have done wrong and how can I fix it so I can play the YouTube videos when they are selected?
I have added my YouTube activity file code here:
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import android.widget.VideoView;
import com.google.android.youtube.player.YouTubeBaseActivity;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayerView;
public class YouTubePlaybackOverlayActivity extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener {
private static String ytUrl;
public String TAG = YouTubePlaybackOverlayActivity.class.getSimpleName();
public VideoView mVideoView;
public LeanbackPlaybackState mPlaybackState = LeanbackPlaybackState.IDLE;
public static final String API_KEY = "XXXXXXXXXXXXXXXXXXXX";
private int mPosition = 0;
private long mStartTimeMillis;
private long mDuration = -1;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
//private GoogleApiClient client;
#Override
public void onStart() {
super.onStart();
// // ATTENTION: This was auto-generated to implement the App Indexing API.
// // See https://g.co/AppIndexing/AndroidStudio for more information.
// client.connect();
// Action viewAction = Action.newAction(
// Action.TYPE_VIEW, // TODO: choose an action type.
// "PlaybackOverlay Page", // TODO: Define a title for the content shown.
// // TODO: If you have web page content that matches this app activity's content,
// // make sure this auto-generated web page URL is correct.
// // Otherwise, set the URL to null.
// Uri.parse("http://host/path"),
// // TODO: Make sure this auto-generated app deep link URI is correct.
// Uri.parse("android-app://software.blackstone.sunnahstreamtv/http/host/path")
// );
// AppIndex.AppIndexApi.start(client, viewAction);
}
#Override
public void onStop() {
super.onStop();
// // ATTENTION: This was auto-generated to implement the App Indexing API.
// // See https://g.co/AppIndexing/AndroidStudio for more information.
// Action viewAction = Action.newAction(
// Action.TYPE_VIEW, // TODO: choose an action type.
// "PlaybackOverlay Page", // TODO: Define a title for the content shown.
// // TODO: If you have web page content that matches this app activity's content,
// // make sure this auto-generated web page URL is correct.
// // Otherwise, set the URL to null.
// Uri.parse("http://host/path"),
// // TODO: Make sure this auto-generated app deep link URI is correct.
// Uri.parse("android-app://software.blackstone.sunnahstreamtv/http/host/path")
// );
// AppIndex.AppIndexApi.end(client, viewAction);
// client.disconnect();
}
/*
* List of various states that we can be in
*/
public enum LeanbackPlaybackState {
PLAYING, PAUSED, IDLE
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** attaching layout xml **/
//setContentView(R.layout.nabawi_video);
//setContentView(R.layout.activity_playback_overlay);
setContentView(R.layout.video_playback);
/** Initializing YouTube player view **/
YouTubePlayerView youTubePlayerView = (YouTubePlayerView) findViewById(R.id.youtube_player);
youTubePlayerView.initialize(API_KEY, this);
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
//client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
// #Override
// protected void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_playback_overlay);
//
// loadViews();
// }
#Override
public void onDestroy() {
stopPlayback();
super.onDestroy();
}
private void loadViews() {
mVideoView = (VideoView) findViewById(R.id.youtube_player);
mVideoView.setFocusable(false);
mVideoView.setFocusableInTouchMode(false);
Movie movie = (Movie) getIntent().getSerializableExtra(DetailsActivity.MOVIE);
//setVideoPath(movie.getVideoUrl());
setVideoPath(movie.getyTubeID());
ytUrl = movie.getyTubeID();
}
public void setVideoPath(String videoUrl) {
setPosition(0);
mVideoView.setVideoPath(videoUrl);
mStartTimeMillis = 0;
mDuration = Utils.getDuration(videoUrl);
}
private void stopPlayback() {
if (mVideoView != null) {
mVideoView.stopPlayback();
}
}
private void setPosition(int position) {
if (position > mDuration) {
mPosition = (int) mDuration;
} else if (position < 0) {
mPosition = 0;
mStartTimeMillis = System.currentTimeMillis();
} else {
mPosition = position;
}
mStartTimeMillis = System.currentTimeMillis();
Log.d(TAG, "position set to " + mPosition);
}
public int getPosition() {
return mPosition;
}
public void setPlaybackState(LeanbackPlaybackState playbackState) {
this.mPlaybackState = playbackState;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_playback_overlay, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void playPause(boolean doPlay) {
if (mPlaybackState == LeanbackPlaybackState.IDLE) {
/* Callbacks for mVideoView */
setupCallbacks();
}
if (doPlay && mPlaybackState != LeanbackPlaybackState.PLAYING) {
mPlaybackState = LeanbackPlaybackState.PLAYING;
if (mPosition > 0) {
mVideoView.seekTo(mPosition);
}
mVideoView.start();
mStartTimeMillis = System.currentTimeMillis();
} else {
mPlaybackState = LeanbackPlaybackState.PAUSED;
int timeElapsedSinceStart = (int) (System.currentTimeMillis() - mStartTimeMillis);
setPosition(mPosition + timeElapsedSinceStart);
mVideoView.pause();
}
}
public void fastForward() {
if (mDuration != -1) {
// Fast forward 10 seconds.
setPosition(mVideoView.getCurrentPosition() + (10 * 1000));
mVideoView.seekTo(mPosition);
}
}
public void rewind() {
// rewind 10 seconds
setPosition(mVideoView.getCurrentPosition() - (10 * 1000));
mVideoView.seekTo(mPosition);
}
private void setupCallbacks() {
mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mVideoView.stopPlayback();
mPlaybackState = LeanbackPlaybackState.IDLE;
return false;
}
});
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
if (mPlaybackState == LeanbackPlaybackState.PLAYING) {
mVideoView.start();
}
}
});
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mPlaybackState = LeanbackPlaybackState.IDLE;
}
});
}
#Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult result) {
Toast.makeText(this, "Failured to Initialize!", Toast.LENGTH_LONG).show();
}
#Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
/** add listeners to YouTubePlayer instance **/
player.setPlayerStateChangeListener(playerStateChangeListener);
player.setPlaybackEventListener(playbackEventListener);
player.setFullscreen(true);
player.setPlayerStyle(YouTubePlayer.PlayerStyle.CHROMELESS);
//player.play();
/** Start buffering **/
for (int i = 0; i < MovieProvider.mItems.size(); i++) {
Movie movie = (Movie) getIntent().getSerializableExtra(DetailsActivity.MOVIE);
player.loadVideo(movie.getyTubeID());
}
}
private YouTubePlayer.PlaybackEventListener playbackEventListener = new YouTubePlayer.PlaybackEventListener() {
#Override
public void onBuffering(boolean arg0) {
}
#Override
public void onPaused() {
}
#Override
public void onPlaying() {
}
#Override
public void onSeekTo(int arg0) {
}
#Override
public void onStopped() {
}
};
private YouTubePlayer.PlayerStateChangeListener playerStateChangeListener = new YouTubePlayer.PlayerStateChangeListener() {
#Override
public void onAdStarted() {
}
#Override
public void onError(YouTubePlayer.ErrorReason arg0) {
}
#Override
public void onLoaded(String arg0) {
}
#Override
public void onLoading() {
}
#Override
public void onVideoEnded() {
}
#Override
public void onVideoStarted() {
}
};
}
The issue was a corrout indexing in the project.
I removed the class file.
Then I cleared the cache, restarted Android Studio and then cleaned and rebuilt the project.
I restarted Android Studio again and then recreated the desired class file(s) and layout files and the project compiled successfully and everything is good.
Thanks everyone for your time, advice, advice and input.
public class PlayerScreen extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {
private MediaPlayer mp;
private Button buttonplaypause;
private int count;
private SeekBar seekbar;
private int curpos, prevpos;
private Bundle b;
private String title;
private final Handler handler = new Handler();
private Runnable updatePositionRunnable = new Runnable() {
public void run() {
seekbar.setProgress(mp.getCurrentPosition());
handler.postDelayed(this, 6000);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player_screen);
title = b.getString("title");
mp = new MediaPlayer();
try {
Log.d("message", "message");
mp.setDataSource(Environment.getExternalStorageDirectory().getPath()+"/Music/"+title);
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
}
//mp = MediaPlayer.create(this, R.raw.audio);
buttonplaypause = (Button) findViewById(R.id.buttonPlayPause);
seekbar = (SeekBar) findViewById(R.id.seekBar);
seekbar.setMax(mp.getDuration());
buttonplaypause.setBackgroundResource(R.drawable.play);
seekbar.setOnSeekBarChangeListener(this);
handler.postDelayed(updatePositionRunnable, 6000);
}
public void onProgressChanged(SeekBar mySeekBar, int progress, boolean fromUser) {
if (mp.isPlaying()) {
mp.seekTo(progress);
}
}
public void onStartTrackingTouch(SeekBar mySeekBar) {
}
public void onStopTrackingTouch(SeekBar mySeekBar) {
}
public void toPlayPause(View v) {
if (count % 2 == 0) {
buttonplaypause.setBackgroundResource(R.drawable.pause);
curpos = mp.getCurrentPosition();
prevpos = curpos;
mp.seekTo(curpos);
mp.start();
count++;
buttonplaypause.setBackgroundResource(R.drawable.play);
mp.pause();
count++;
}
}
}
What i'm trying to do is build a music player which displays the list of song in one activity in a List View and when the user taps on an item that particular song should be played in another intent (which is provided by play and pause button). The code provided above is the code for the second activity (the first part i.e. listing the songs is done). The first Activity passes the song title in a bundle which is received by this activity. I am new to android and don't know a lot about it. I don't know how to pass the song from one intent to another so that it is played. The problem I think is in the line setDataSource().
When the second Intent (i.e the code provided above) is opened on tapping item in the List View, the seek bar reaches it's end and no song is played
If there is any other, better way to pass the song from one intent to another feel free to describe it in detail.
I am interested in being able to "prebuffer" VideoView A while VideoView B is playing. Is this possible?
I have two instances of a VideoView.
Only one VideoView will be displayed at a given time, taking up the entire screen of the phone.
The purpose is to reduce the "black screen" when switching from VideoView A and VideoView B.
The app plays a list of videos one after another.
Added Below Code on Jan 19, 2015
The code below grabs a reference to each Player's MediaPlayer. When MediaPlayer A begins rendering, MediaPlayer B will call stop(), release(), setDataSource(url), prepareAsync(). When MediaPlayer A completes, Media Player B will call start().
public class PrebufferingActivity extends Activity {
private VideoView player1;
private VideoView player2;
private MediaPlayer mediaPlayer1;
private MediaPlayer mediaPlayer2;
public static final String URL_1 = "sample1.mp4";
public static final String URL_2 = "sample2.mp4";
public boolean FIRST_TIME = true;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_prebuffering);
player1 = (VideoView) findViewById(R.id.videoPlayer1);
player2 = (VideoView) findViewById(R.id.videoPlayer2);
player1.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return false;
}
});
player2.setOnTouchListener(new OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return false;
}
});
player1.setOnCompletionListener(new OnCompletionListener(){
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer2.start();
// Toggle visibility. Player1 is completed. Hide Player1. Show Player2.
player2.setVisibility(View.VISIBLE);
player1.setVisibility(View.INVISIBLE);
}
});
player1.setOnInfoListener(new OnInfoListener(){
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra)
{
if(what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
{
mediaPlayer2.stop();
mediaPlayer2.release();
try {
mediaPlayer2.setDataSource(URL_2);
mediaPlayer2.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
});
player1.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer1 = mp;
if(FIRST_TIME == true) {
mediaPlayer1.start();
player1.requestFocus();
FIRST_TIME = false;
}
}
});
player2.setOnCompletionListener(new OnCompletionListener(){
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer1.start();
player1.requestFocus();
// Toggle visibility. Player2 is completed. Hide Player2. Show Player1.
player1.setVisibility(View.VISIBLE);
player2.setVisibility(View.INVISIBLE);
}
});
player2.setOnInfoListener(new OnInfoListener(){
#Override
public boolean onInfo(MediaPlayer mp, int what, int extra)
{
if(what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
{
// Prepare Player 2
mediaPlayer1.stop();
mediaPlayer1.release();
try {
mediaPlayer1.setDataSource(PrebufferingActivity.URL_1);
mediaPlayer1.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
});
player2.setOnPreparedListener(new OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer2 = mp;
}
});
// Player 1
player1.setMediaController(new MediaController(this));
player1.setVideoURI(Uri.parse(URL_1));
// Player 2
player2.setMediaController(new MediaController(this));
player2.setVideoURI(Uri.parse(URL_2));
}
Assuming you are using MediaPlayer to handle the playback of your videos within your VideoView, you can use the prepareAsync() method to achive this. The prepareAsync() method essentially performs the same function as prepare(), which is used to buffer and prepare a video, except it can be done asynchronously in the background.
EDIT
I did something similiar but I actually used SurfaceView. To handle another stream, simply create another instance of MediaPlayer. The following example will create two instances of MediaPlayer and buffer the first video. After the first video is prepared, the second video will be asynchronously buffered. The first MediaPlayer is then bound to the SurfaceView and the first video is started. When the first video is finished playing, the corresponding instance of MediaPlayer is released, the secondary instance is attached, and the second video is automatically started. The following example code has been tested and works fine:
public class StreamingActivity extends Activity implements SurfaceHolder.Callback, MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener
{
MediaPlayer mediaPlayerPrimary;
MediaPlayer mediaPlayerSecondary;
SurfaceHolder surfaceHolder;
SurfaceView surfaceView;
String videoSourcePrimary = "videoSourcePrimaryURL";
String videoSourceSecondary = "videoSourceSecondaryURL";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.streaming_activity_layout);
/** Create SurfaceView */
surfaceView = (SurfaceView) findViewById(R.id.surface_view);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder arg0)
{
try
{
/** Create MediaPlayer(s) */
mediaPlayerPrimary = new MediaPlayer();
mediaPlayerSecondary = new MediaPlayer();
/** Attach primary MediaPlayer to SurfaceView */
mediaPlayerPrimary.setDisplay(surfaceHolder);
/** Set sources */
mediaPlayerPrimary.setDataSource(videoSourcePrimary);
mediaPlayerSecondary.setDataSource(videoSourceSecondary);
/** Prepare MediaPlayer(s) */
mediaPlayerPrimary.prepare();
mediaPlayerSecondary.prepareAsync();
/** Set listeners */
mediaPlayerPrimary.setOnPreparedListener(this);
mediaPlayerPrimary.setOnCompletionListener(this);
mediaPlayerSecondary.setOnPreparedListener(this);
mediaPlayerSecondary.setOnCompletionListener(this);
/** Set audio stream type */
mediaPlayerPrimary.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayerSecondary.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
catch (Exception e)
{
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
{
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0)
{
}
#Override
public void onPrepared(MediaPlayer mp)
{
if (mp == mediaPlayerPrimary)
{
/** First video ready, start playback */
mediaPlayerPrimary.start();
}
else if (mp == mediaPlayerSecondary)
{
/** Second video is ready */
}
}
#Override
public void onCompletion(MediaPlayer mp)
{
/** First video is completed, start second video */
mediaPlayerPrimary.release();
mediaPlayerSecondary.setDisplay(surfaceHolder);
mediaPlayerSecondary.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.streaming_activity_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings)
{
return true;
}
return super.onOptionsItemSelected(item);
}
}
Hey I'm having trouble getting a stream to play from my localhost server (and also other websites with raw mp3 files). My code work for the site that is commented out so i assume it has something to
do with the server and not the java code.
public class MainActivity extends ActionBarActivity{
//static final String ANCHOR = "http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3";
static final String ANCHOR = "http://spintron.ddns.net/Random%20Access%20Memories/07%20-%20Touch.mp3";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MediaPlayer mp = new MediaPlayer();
mp.setVolume(1, 1);
try{
mp.setDataSource(ANCHOR);
mp.prepareAsync();
}catch(Exception e){
e.printStackTrace();
}
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
Toast.makeText(MainActivity.this,"Prepared",Toast.LENGTH_LONG).show();
mp.start();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
To play music file refer below code.
my res/raw folder contains options_music.wav music file.
// Play Music
MediaPlayer mp = new MediaPlayer();
AssetFileDescriptor descriptor;
try {
descriptor = getAssets().openFd("options_music.wav");
mp.setDataSource(descriptor.getFileDescriptor(),
descriptor.getStartOffset(), descriptor.getLength());
descriptor.close();
mp.prepare();
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
//Log.e("Music", "Music Completed........");
mp.start();
}
});
} catch (Exception e) {
Log.e("ErrorMusic", "Cant Play Music File"+e);
}
For your url , make sure your it is properly url encoded and accessible from your mobile.
My ProgressDialog will not show up. In my program the user selects bitrate from a pop up menu, the content is fetched online and displayed in VideoView.
However, all I get is a black screen while the video loads and the progressDialog is display for a split second (or less) at end before the video finally loads.
private void showPopupMenu(View v){
popupMenu = new PopupMenu(VideoPlayer.this, v);
if(bitRates != null){
int menuItem = 0;
int index = bitRates.size()-1;
popupMenu.getMenu().add(0,menuItem, 0,"Hide menu");
for(int i=1;i<bitRates.size();i++){
menuItem = i;
popupMenu.getMenu().add(0,menuItem, 0,"Quality"+" : "+bitrateCheck(bitRates.get(index))).setCheckable(true);
Log.i("ITEM",qualityList.get(i)+" : "+bitRates.get(i));
index--;
}
popupMenu.getMenu().add(0,menuItem++, 0,"Catalog");
}
popupMenu.show();
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(final MenuItem item) {
p_dialog = ProgressDialog.show(VideoPlayer.this, "", "Loading...");
//get current position of video to seek to
final int position = mVideoView.getCurrentPosition();
new Thread() {
public void run() {
try{
runOnUiThread(new Runnable() {
public void run() {
if(item.getTitle().equals("Catalog")){
backButtonVideo(new View(VideoPlayer.this));
}
else if(item.getTitle().equals("Hide menu")){
popupMenu.dismiss();
mVideoView.start();
}
else{
play(streamUrls.get(item.getItemId()),position);
}
}
});
}
catch (Exception e) {
Log.e("tag", e.getMessage());
}
p_dialog.dismiss();
}
}.start();
return true;
}
});
}
public void play(String _videoUri, int position){
Log.i(TAG,"URI is : "+Uri.parse(_videoUri).toString());
//View view = new View()
MediaController mc = new MediaController(VideoPlayer.this);
mVideoView.setMediaController(mc);
mVideoView.setVideoURI(Uri.parse(_videoUri));
mVideoView.requestFocus();
mVideoView.seekTo(position);
mVideoView.start();
}
////////////////////////Edit with new Code: as per suggestions/////////////////////
Now the dialog does not show at all.
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
mVideoView.start();
}
});
///////////////////////////////////////////////////////////////////////////////////
popupMenu.show();
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(final MenuItem item) {
//get current position of video to seek to
final int position = mVideoView.getCurrentPosition();
p_dialog = ProgressDialog.show(VideoPlayer.this, "", "Loading...");
try{
if(item.getTitle().equals("Catalog")){
backButtonVideo(new View(VideoPlayer.this));
}
else if(item.getTitle().equals("Hide menu")){
popupMenu.dismiss();
mVideoView.start();
}
else{
play(streamUrls.get(item.getItemId()),position);
}
}
catch (Exception e) {Log.e("tag", e.getMessage());}
return true;
}
});
}
public void play(String _videoUri, int position){
Log.i(TAG,"URI is : "+Uri.parse(_videoUri).toString());
MediaController mc = new MediaController(VideoPlayer.this);
mVideoView.setMediaController(mc);
mVideoView.setVideoURI(Uri.parse(_videoUri));
mVideoView.requestFocus();
mVideoView.seekTo(position);
p_dialog.dismiss();
}
Firstly, it makes no sense to create a separate thread only to run something back on the UI thread (why do you create the thread in the first place then?).
onMenuItemClick should already be called by the UI thread (callbacks for UI elements generally do this).
What you should look at is using a MediaPlayer.OnPreparedListener with VideoView.setOnPreparedListener. This will give you an indication of when the video is ready to be played.
I did some rearrangement as per Che Jami and got it to work. Thanks
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
p_dialog.dismiss();
mVideoView.start();
}
});
////////////////////////////////////////////////////////////////////////////////
popupMenu.show();
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(final MenuItem item) {
//get current position of video to seek to
final int position = mVideoView.getCurrentPosition();
try{
if(item.getTitle().equals("Catalog")){
backButtonVideo(new View(VideoPlayer.this));
}
else if(item.getTitle().equals("Hide menu")){
popupMenu.dismiss();
mVideoView.start();
}
else{
p_dialog = ProgressDialog.show(VideoPlayer.this, "", "Loading new stream");
play(streamUrls.get(item.getItemId()),position);
}
}
catch (Exception e) {Log.e("tag", e.getMessage());}
return true;
}
});
}
public void play(String _videoUri, int position){
Log.i(TAG,"URI is : "+Uri.parse(_videoUri).toString());
MediaController mc = new MediaController(VideoPlayer.this);
mVideoView.setMediaController(mc);
mVideoView.setVideoURI(Uri.parse(_videoUri));
mVideoView.requestFocus();
mVideoView.seekTo(position);
}
I have the same problem...i've tried you solution but my progress gets blocked...everything stops...and video doesn't show up...it seems that onPrepareListener is never called up...any ideas? Also it seems that setVideoURI has never passed in code...:/
I have different versions of code...with threads, with runOnUI, with AsyncTask, without everything...nothing seems to be working fully. something is always missing.
EDIT:
I have function that I'm calling in onClickListener
Here is a code like yours without any threads:
Version 1: Video starts after few seconds, progress dialog just show for a moment when video starts. Progress isn't showed from the beginning.
public void loadService(final int mode) {
//Version 1
// Show dialog
loadService = new ProgressDialog(activity);
loadService.setTitle("Loading service");
loadService.setMessage("Please wait...");
loadService.setCancelable(false);
loadService.show();
// Hide progress dialog after 15 seconds if nothing happens
DuoTVGuiHandler.progressBarProttection(loadService, 15);
// Setup video view for playback
if (mode == STAND_ALONE) {
setupVideoView(((DuoTVGuiActivity) activity).getVideoPlayback());
}
if (mode == WIDGET_MODE) {
setupVideoView(((MainActivity) activity).getVideoViewWidgetMode());
}
}
/** Setup video view for playback */
public void setupVideoView(final VideoView videoView) {
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
loadService.dismiss();
videoView.start();
}
});
videoView.setVideoURI(Uri.parse(channels.get(index).getFilePath()));
}
Version 2 with thread and handler...progress dialog is showed...its spinning...video shows for a second...and the app crashes...WrongThread for UI exception...but when i move setVideoURI in runOnUiThread...progress just stays forever...and setOnVideoURI is never finished.
public void loadService(final int mode) {
// //////////////////////////////
// Version 2
// //////////////////////////////
// Show dialog
loadService = new ProgressDialog(activity);
loadService.setTitle("Loading service");
loadService.setMessage("Please wait...");
loadService.setCancelable(false);
loadService.show();
final Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
loadService.dismiss();
super.handleMessage(msg);
}
};
Thread loadVideoPath = new Thread(new Runnable() {
public void run() {
if (mode == STAND_ALONE) {
((DuoTVGuiActivity) activity)
.getVideoPlayback()
.setVideoURI(
Uri.parse(channels.get(index).getFilePath()));
}
if (mode == WIDGET_MODE) {
((MainActivity) activity)
.getVideoViewWidgetMode()
.setVideoURI(
Uri.parse(channels.get(index).getFilePath()));
}
handler.sendEmptyMessage(0);
}
});
loadVideoPath.start();
}
Hope you have some idea...I've lost few days on this...and cant see solution...for this pretty basic thing...it drives me crazy :)