How to add subtitles to VideoView? - android

I am wondering how to successfully add subtitles to VideoView. I do not know how to do it. I do not know how to use addSubtitleSource, addTimedTextSource methods properly and if they are correct.
Android documentation says that addTimedTextSource is used only with MediaPlayer (which VideoView isn't) but there are some information about track i.e. getTrackInfo and others. I do not know where to start. There are some solutions in the internet but I do not understand those code snippets and I think they do not give an easy solutions.
Does anybody can help me?
Let's have a simple VideoView with video attached. What's next?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video);
videoView = findViewById(R.id.video_view1);
MediaController mMedia = new MediaController(this);
mMedia.setMediaPlayer(videoView);
mMedia.setAnchorView(videoView);
videoView.setMediaController(mMedia);
String path1 = VIDEO_URL;
Uri uri = Uri.parse(path1);
videoView.setVideoURI(uri);
videoView.start();
}
EDIT:
I've added the listener to VideoView and then OnTimedTextListener to MediaPlayer mp. Is this MediaPlayer mp attached to my VideoView? Is this the correct way to create MediaPlayer which will correspond with the VideoView?
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
try {
mp.addTimedTextSource("android.resource://"+getPackageName()+"/"+ R.raw.sub,MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP);
} catch (IOException e) {
e.printStackTrace();
}
mp.setOnTimedTextListener(new MediaPlayer.OnTimedTextListener() {
#Override
public void onTimedText(MediaPlayer mp, TimedText text) {
text.getBounds();
text.getText();
}
});
I do not know how to use getBounds() and getText() methods.
EDIT 2:
Now I have made something like this...
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
try {
mp.addTimedTextSource("android.resource://" + getPackageName() + "/"+R.raw.sub,
MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP);
} catch (IOException e) {
e.printStackTrace();
}
mp.selectTrack(2);
mp.setOnTimedTextListener(new MediaPlayer.OnTimedTextListener() {
#Override
public void onTimedText(MediaPlayer mp, TimedText text) {
txtDisplay.setText(text.getText());
}
});
mp.start();
}
});
I put the "android.resource://" + getPackageName() + "/"+R.raw.sub path to the file but it gives me an error E/TaskPersister: File error accessing recents directory (directory doesn't exist?). Later I moved it to the assets folder but the result was the same. What's wrong?
I've added the mp.selectTrack(2); with index = 2 because I read somewhere that this is obligatory and for the videos getTrackInfo returns 2 in most cases.
In the end I thought that txtDisplay.setText() method will be OK. Is it?
Please tell me, is only 1 the issue here or more?

You could use ExoPlayer library for this purpose. Here is a medium post that explains how you could add an SRT subtitle to ExoPlayer tracks.

Related

android VideoView can't play this video error

I was trying to play a video by streaming it from internet.
videoView = findViewById(R.id.videoView);
bufferProgress = findViewById(R.id.bufferProgress);
videoURL = "https://firebasestorage.googleapis.com/v0/b/sample2-e4836.appspot.com/o/Video%2FFourthVideo.mp4?alt=media&token=6106b76c-be43-4fb6-b29f-64df699bec3d";
Uri uri = Uri.parse(videoURL);
videoView.setVideoURI(uri);
videoView.requestFocus();
bufferProgress.setVisibility(View.VISIBLE);
videoView.start();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
#Override
public void onVideoSizeChanged(MediaPlayer mediaPlayer, int i, int i1) {
bufferProgress.setVisibility(View.INVISIBLE);
mediaPlayer.start();
}
});
}
});
this code I'm using right now in my onCreate.
At first it was working good.
But then I just changed my videoURL with diffrent link.
& since then I'm getting this error, not just for one I tried many different links but the problem was same.
But for first link again there is no problem for playing video.
after that I revoked those links of videos. and now I'm getting an error that Unfortunately this app has stopped!
note:
other activities of my app works fine.
try any links as your wish.

Make Video Streaming URL secure from Logging in Logcat

Currently I'm trying to simply stream a Video from some link this way:
try {
videoView = (VideoView) findViewById(R.id.videoView);
MediaController vidControl = new MediaController(this);
vidControl.setAnchorView(videoView);
videoView.setMediaController(vidControl);
videoView.setVideoPath("http://some.link/some_video.mp4");
loadingProgress.show();
videoView.requestFocus();
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
loadingProgress.dismiss();
videoView.start();
}
});
} catch (Exception e) {
e.printStackTrace();
}
Everything is going OK, but I want to make that URL (i.e. http://some.link/some_video.mp4) secure. I mean user won't be able to download this video.
The problem is: before loading this video, the logcat is
displaying log like this:
my.app.package.name W/MediaPlayer: Couldn't open http://some.link/some_video.mp4: java.io.FileNotFoundException: No content provider: http://some.link/some_video.mp4
I have noticed:
Even the code is not going into CATCH block.
Made SIGNED App, but that LOG is still appearing.
Those logs are built into the framework MediaPlayer class. The only way I know of to remove it is to take the MediaPlayer code from AOSP, copy it to a class in your app, remove all the log statements, and use that instead of the Android MediaPlayer class.

Cant Play Video ( .mp4) uploaded from iPhone on Android

Actually i made one application for iphone and android device.. and in that video feature is available so video uploaded by iphone device,video (mp4) is cant played in android device so please any body help me
pDialog = new ProgressDialog(this);
// Set progressbar message
pDialog.setMessage("Buffering...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
// Show progressbar
pDialog.show();
try {
// Start the MediaController
MediaController mediacontroller = new MediaController(
PlayVideoViewFromURLActivity.this);
mediacontroller.setAnchorView(mVideoView);
// Get the URL from String VideoURL
Uri videoUri = Uri.parse(vidUrl); // vidUrl is url of video which on server
mVideoView.setMediaController(mediacontroller);
mVideoView.setVideoURI(videoUri);
} catch (Exception e) {
e.printStackTrace();
}
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new OnPreparedListener() {
// Close the progress bar and play the video
public void onPrepared(MediaPlayer mp) {
pDialog.dismiss();
mVideoView.start();
}
});
mVideoView.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
if (pDialog.isShowing()) {
pDialog.dismiss();
}
finish();
}
});
full Logcat error :
08-13 09:45:10.062: D/MediaPlayer(1929): Couldn't open file on client side, trying server side
08-13 09:45:11.770: E/MediaPlayer(1929): error (1, -2147483648)
08-13 09:45:11.790: E/MediaPlayer(1929): Error (1,-2147483648)
08-13 09:45:11.790: D/VideoView(1929): Error: 1,-2147483648
There is an alternative approach for streaming video using the MediaPlayer class,like we use it in creating a music player. You can stream media, including video, to a MediaPlayer object using a surface view. For example, you could use the following layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<SurfaceView
android:id="#+id/surfView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
MainActivity.java
public class TestAct extends Activity implements SurfaceHolder.Callback, OnPreparedListener
{
private MediaPlayer mediaPlayer;
private SurfaceHolder vidHolder;
private SurfaceView vidSurface;
String vidAddress = "https://archive.org/download/ksnn_compilation_master_the_internet/ksnn_compilation_master_the_internet_512kb.mp4";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
vidSurface = (SurfaceView) findViewById(R.id.surfView);
vidHolder = vidSurface.getHolder();
vidHolder.addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder arg0)
{
try
{
mediaPlayer = new MediaPlayer();
mediaPlayer.setDisplay(vidHolder);
mediaPlayer.setDataSource(vidAddress);
mediaPlayer.prepare();
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
catch (Exception e)
{
e.printStackTrace();
}
}
#Override
public void onPrepared(MediaPlayer mp)
{
mediaPlayer.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
{
}
}
Hope this helps :)
Issue:
It is issue about conflict of encoding-decoding between the video and the device's platform support.
Solution:
I would insist to use Vitamio library to play the videos in android.
It is pretty simple to use and reliable also.
Example:
You can add it to your xml file like VideoView,
<io.vov.vitamio.widget.VideoView
android:id="#+id/surface_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
You can easily control the player,
public class VideoViewDemo extends Activity {
/**
* TODO: Set the path variable to a streaming video URL or a local media file
* path.
*/
private String path = "";
private VideoView mVideoView;
private EditText mEditText;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
if (!LibsChecker.checkVitamioLibs(this))
return;
setContentView(R.layout.videoview);
mEditText = (EditText) findViewById(R.id.url);
mVideoView = (VideoView) findViewById(R.id.surface_view);
if (path == "") {
// Tell the user to provide a media file URL/path.
Toast.makeText(VideoViewDemo.this, "Please edit VideoViewDemo Activity, and set path" + " variable to your media file URL/path", Toast.LENGTH_LONG).show();
return;
} else {
/*
* Alternatively,for streaming media you can use
* mVideoView.setVideoURI(Uri.parse(URLstring));
*/
mVideoView.setVideoPath(path);
mVideoView.setMediaController(new MediaController(this));
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
// optional need Vitamio 4.0
mediaPlayer.setPlaybackSpeed(1.0f);
}
});
}
}
public void startPlay(View view) {
String url = mEditText.getText().toString();
path = url;
if (!TextUtils.isEmpty(url)) {
mVideoView.setVideoPath(url);
}
}
public void openVideo(View View) {
mVideoView.setVideoPath(path);
}
}
Reference:
VideoViewDemo
I hope it will be helpful to you.
Can't Play video in android uploded from iphone
Why mp4 does not play in 4 steps:
download you vidView URL to PC with 'ffmpeg'
$ffmpeg -i $downloadFileName
inspect details of reported codecs
compare those reported codecs to what android media supports
Note: very likely that #2 will report codecs not listed at #4
Although the video is .mp4, the video is compressed on iOS in a way that the native android media player cannot play/decode.
I ran into this exact problem OP had when developing for cross platform. An easy alternative is using VLC for Android, which is open source and built upon FFMPEG and utilizes SurfaceViews.
To do this, include the below in your build.grade file:
compile "de.mrmaffen:vlc-android-sdk:1.0.3"
For example, you can then make a new activity for the Video, and in the onCreate, do the following:
mSurfaceView = (SurfaceView) findViewById(R.id.player_surface);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceFrame = (FrameLayout) findViewById(R.id.player_surface_frame);
mMediaUrl = getIntent().getExtras().getString("videoUrl");
try {
mLibVLC = LibVLC.getInstance();
mLibVLC.setAout(mLibVLC.AOUT_AUDIOTRACK);
mLibVLC.setVout(mLibVLC.VOUT_ANDROID_SURFACE);
mLibVLC.setHardwareAcceleration(LibVLC.HW_ACCELERATION_FULL);
mLibVLC.eventVideoPlayerActivityCreated(Boolean.TRUE);
mLibVLC.init(getApplicationContext());
} catch (LibVlcException e){
Log.e(TAG, e.toString());
}
mSurfaceHolder.addCallback(mSurfaceCallback);
mSurface = mSurfaceHolder.getSurface();
mLibVLC.attachSurface(mSurface, VideoVLCActivity.this);
mLibVLC.playMRL(mMediaUrl);
Lots of info can be found here for troubleshooting:
VLC for Android VideoLAN Forums
There is a more detailed example here, although it uses a different version of libvlc.LibVLC and contains different methods, but it will give you a good idea of what steps are needed to add controls, set the proper size, aspect ratio, orientation etc.

Streaming video with videoview

My code below to streaming video:
VideoView vv = (VideoView)this.findViewById(R.id.screen_video);
Uri uri = Uri.parse(URL);
vv.setVideoURI(uri);
vv.start();
It works.
But if the URL video's format not support by android phone or pad.
It show a dialog, and not show the screen.
But it still streaming with black screen.
I want to get the error message, and access as an exception.
But I don't know how to get it?
Another problem is that the streaming may crash cause by low speed wifi.
How to check it to wait while low speed wifi?
try this code,it work,
public class PlayVideo extends Activity
{
private String videoPath ="url";
private static ProgressDialog progressDialog;
String videourl;
VideoView videoView ;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.play_video);
videoView = (VideoView) findViewById(R.id.videoView);
progressDialog = ProgressDialog.show(PlayVideo.this, "", "Buffering video...", true);
progressDialog.setCancelable(true);
PlayVideo();
}
private void PlayVideo()
{
try
{
getWindow().setFormat(PixelFormat.TRANSLUCENT);
MediaController mediaController = new MediaController(PlayVideo.this);
mediaController.setAnchorView(videoView);
Uri video = Uri.parse(videoPath );
videoView.setMediaController(mediaController);
videoView.setVideoURI(video);
videoView.requestFocus();
videoView.setOnPreparedListener(new OnPreparedListener()
{
public void onPrepared(MediaPlayer mp)
{
progressDialog.dismiss();
videoView.start();
}
});
}
catch(Exception e)
{
progressDialog.dismiss();
System.out.println("Video Play Error :"+e.toString());
finish();
}
}
}
It depends on which Android Version you are developing your application on. There are certain devices which do not support running .mp4 file. Go through Android Media support for more information. Check if you can play any .3gp files or not.
You shouldn't play the video instantly. Add OnPrepared listener to the video view and start the video playing after it. With MediaPlayer you could keep track of the buffering state and stop the video for a while when its not yet downloaded. Please have a look at this guide.
Try Intent to avoid that error. or put try catch in your block.
VideoView can only Stream 3gp videos but i recommend this code to stream your video
public void onCreate(Bundle savedInstanceState){
setContentView(R.layout.main);
String videourl = "http://something.com/blah.mp4";
Uri uri = Uri.parse(videourl);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setDataAndType(uri, "video/mp4");
startActivity(intent);
}
Or Click here to watch Android Video Streaming Tutorial.

rtsp video performance as Browser triggered intent vs my application triggered intent

Hi I am creating an app which will play livestream.com's rtsp live channel.
I am launching the player using intent within my app as following:
iPlayer = new Intent(Intent.ACTION_VIEW);
//iPlayer.setType("video/*");
iPlayer.setData(Uri.parse(videoUrl));
startActivity(iPlayer);
When the media player is launched through my Application, the video performance is very poor. It stops for buffering every few seconds, plays for few seconds and pauses for buffering again.
ON the other hand, If I open the url in android browser (eg. http://m.livestream.com/abcalbania) it has a video tag on that page and triggers video player. THIS time, the video runs very smooth.
Any Idea why this might happen? And how this can be fixed?
I do not want to launch browser URL as intent.
This is done on Atmel cortex A9 chipset with Android 2.3.4
The problem is caused by the codecs that probably are not supported by your player.
for example i have a video created with MPEG Audio codec along with the H.264 video codec.
if i launch the video through my Application the video runs smoothly, but if i launch a video in Ooyala Hook Player it has a very poor performance, it plays the video every 3 seconds, the reason is that the stream use MPEG audio codec instead of AAC Audio codec that is supported.
You will find the answer with:
what codecs are used to create de video, and what are supported by
your player?
Use this code for smooth STREAM
String videoUrl = "rtmp://mystream";
Intent i = new Intent(android.content.Intent.ACTION_VIEW);
i.setDataAndType(Uri.parse(videoUrl), "video/*");
startActivity(i);
Why not you play this in your own activity, create activity and render the video view like
private String path2 = "rtsp://...";
Uri video = Uri.parse(path2);
mVideoView.setVideoURI(video);
mVideoView.setMediaController(new MediaController(this));
mVideoView.requestFocus();
mVideoView.postInvalidateDelayed(100);
mVideoView.start();
Also you can buffer before start playing maybe 5 secs and than successive buffering will be fast. you can control more thing by your own.
Android's MediaPlayer handle very well RTSP - don't open an external app - it's not necessary and product-wise wrong.
About your question - the browser might send another parameters to the video player that help the video play smooth, I didn't check it but it sounds like the only possible option for what you're describing. Example for the extra param might be the video resolution / encoding / size .. you can get all of them easily using MediaMetaDataRetriever.
If you don't want to use the native VideoView or MediaPlayer you can always add external player to your
app, like libVLC or Vitamio.
I recommend of using Vitamio, is really easy to use and integrate. LibVLC is in native code, it means you'll have to build it using ndk and add its libs to your project.
You can find here how to do that.
Android video view support RTSP urls well no need to pass intent to other application.Try out with this code, pass xml with declaration of video view and find it inside this activity.
public class VideoPlayer extends Activity
{
private VideoView mVideoView;
String videoURL="";
static Utility utility;
static Context context;
//MediaController mediaController;
//int iCurrentpostion=0;
int counter=0;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_video_player);
setupViews();
}
private void setupViews()
{
context=VideoPlayer.this;
//utility=new Utility(VideoPlayer.this);
showProgressDialog("Please wait", "Loading video..");
//videoURL=getIntent().getExtras().getString("url");
mVideoView=(VideoView)findViewById(R.id.xvdvwTab);
// mediaController=new MediaController(context);
// mVideoView.setMediaController(mediaController);
mVideoView.setOnPreparedListener(new OnPreparedListener()
{
#Override
public void onPrepared(MediaPlayer mp)
{
utility.hideProgressDialog();
mVideoView.start();
mVideoView.requestFocus();
}
});
mVideoView.setOnCompletionListener(new OnCompletionListener()
{
#Override
public void onCompletion(MediaPlayer mp)
{
finish();
}
});
mVideoView.setOnErrorListener(new OnErrorListener()
{
#Override
public boolean onError(MediaPlayer mp, int what, int extra)
{
utility.hideProgressDialog();
return false;
}
});
playVideoFile();
}
private void playVideoFile()
{
try
{
mVideoView.setVideoURI(Uri.parse("your url"));
}
catch (Exception e)
{
utility.hideProgressDialog();
if (mVideoView != null)
{
mVideoView.stopPlayback();
}
}
}
#Override
protected void onResume()
{
/*if(mVideoView!=null)
{
//setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mVideoView.requestFocus();
if(iCurrentpostion!=0)
mVideoView.seekTo(iCurrentpostion);
mVideoView.start();
}
super.onResume();*/
}
#Override
protected void onDestroy()
{
try
{
if (mVideoView != null)
{
mVideoView.stopPlayback();
mVideoView=null;
}
super.onDestroy();
} catch (Exception e)
{}
}
public void showProgressDialog(String title,String Message)
{
hideProgressDialog();
progressDialog=new ProgressDialog(mActivity);
progressDialog.setTitle(title);
progressDialog.setMessage(Message);
if(Constant.isActivityisRunning)
progressDialog.show();
}
public void hideProgressDialog()
{
if (progressDialog != null)
{
if (progressDialog.isShowing())
{
progressDialog.dismiss();
progressDialog = null;
}
}
}
}
I think play video by Asynchronously for better performance. My code is:
private class myAsync extends AsyncTask<Void, Integer, Void> {
int duration = 0;
//int current = 0;
#Override
protected Void doInBackground(Void... params) {
videoView.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
progressDialog.dismiss();
videoView.seekTo(check);
videoView.start();
duration = videoView.getDuration();
}
});
do {
current = videoView.getCurrentPosition();
System.out.println("duration - " + duration + " current- "
+ current);
}
if (sync.isCancelled())
break;
} while (current != duration || current == 0);
return null;
}
}

Categories

Resources