freinds,
i am using following code to display a mp4 video in my application
and facing following problems
i have seen so many posts related to this issue on google and stackoverflow but every one giving his own suggestions and there is no common answer.
1) i cannot see video in emulator
2) in different phone sometime rarly video is played and most of the time it give above message.
my code
VideoView myVideoView = (VideoView)findViewById(R.id.videoview);
String viewSource ="http://dev.hpac.dev-site.org/sites/default/files/videos/about/mobile.mp4";
myVideoView.setVideoURI(Uri.parse(viewSource));
myVideoView.setMediaController(new MediaController(this));
myVideoView.requestFocus();
myVideoView.start();
any one guide me what is the solution to this problem
any help would be appreciated.
you can make a output stream using your file and get absolute path of stream then put path to video view
private String getDataSource(String path) throws IOException {
if (!URLUtil.isNetworkUrl(path)) {
return path;
} else {
URL url = new URL(path);
URLConnection cn = url.openConnection();
cn.connect();
InputStream stream = cn.getInputStream();
if (stream == null)
throw new RuntimeException("stream is null");
File temp = File.createTempFile("mediaplayertmp", "dat");
temp.deleteOnExit();
String tempPath = temp.getAbsolutePath();
#SuppressWarnings("resource")
FileOutputStream out = new FileOutputStream(temp);
byte buf[] = new byte[128];
do {
int numread = stream.read(buf);
if (numread <= 0)
break;
out.write(buf, 0, numread);
} while (true);
try {
stream.close();
} catch (IOException ex) {
Log.e(TAG, "error: " + ex.getMessage(), ex);
}
return tempPath;
}
}
and
public void initVideo() {
try {
if (!mVideoView.isPlaying()) {
if (url > playList.size() - 1) {
url = 0;
}
String[] playurl = (playList.get(url)).split("\\.");
String urlExtention = playurl[playurl.length - 1];
if (urlExtention.equals("mp4")) {
playVideo(playList.get(url));
} else if (urlExtention.equals("jpg")
|| urlExtention.equals("jpeg")) {
Intent intentShedule = new Intent(Default_Player.this,
ImagePlayer.class);
intentShedule.putExtra("imagePath", playList.get(url));
intentShedule.putExtra("urlValue", url);
intentShedule.putExtra("playlistType", playlistType);
intentShedule.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intentShedule);
finish();
} else {
Intent intentShedule = new Intent(Default_Player.this,
WebContentView.class);
intentShedule.putExtra("webPath", playList.get(url));
intentShedule.putExtra("urlValue", url);
intentShedule.putExtra("playlistType", playlistType);
intentShedule.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intentShedule);
finish();
}
}
mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
System.out.println("set on error listner");
//do somthing if alert this video can not be played
return false;
}
});
mVideoView
.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer vmp) {
playnew();
}
});
} catch (Exception e) {
}
// TODO Auto-generated method stub
}
use on error listner if alert this video can not be played
in eclipse emulator video not displayed that link from website(internet).
if you want to play a specific video. then make raw folder and give following path
String path1="android.resource://your package name/"+ R.raw.video name;
Uri uri=Uri.parse(path1);
videoView.setVideoURI(uri);
Related
I am trying to creae mediaplayer from file path
private void play(String path) {
MediaPlayer player = null;
if (path.startsWith("assets/music")) {
path = path.replace("assets/", "");
AssetFileDescriptor afd;
try {
afd = mActivity.getAssets().openFd(path);
player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor(),
afd.getStartOffset(), afd.getLength());
player.prepare();
} catch (IOException e) {
Log.e(TAG, e.toString());
}
} else {
player = MediaPlayer.create(mActivity, Uri.parse(path));
}
if (player != null) {
player.setOnCompletionListener(releaseListener);
player.setOnErrorListener(new OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.e(TAG, "mp error: " + what + ", extra: " + extra);
return true;
}
});
player.start();
mPlayer = player;
}
}
from assets path it works but MediaPlayer.create(mActivity, Uri.parse(path)); always returns null
full path is
/storage/emulated/0/Download/Buzzer - 1.mp3
assets path is
assets/music/Buzzer - 1.mp3
If you are saying that the value of path that you are passing to Uri.parse(path) is /storage/emulated/0/Download/Buzzer - 1.mp3, that is not a valid Uri. Notably, there is no scheme. Either:
Pass in a File that points to your desired file and use Uri.fromFile(), or
Ensure that path has a scheme (e.g., file:///storage/emulated/0/Download/Buzzer - 1.mp3)
I'm downloading MP4 files from a Web app to a file on my mobile device. Since the files tend to be large, I want to start playing them as soon as I get some data, rather than wait until the whole file has been downloaded, so I've come up with the following scheme:
Download the first 1 MB of data to a file on my SD card.
Start the video player.
Download the remaining data in 1 MB chunks, appending the new data to the original file.
More precisely, the code does the following:
Create a FileOutputstream named out that writes to "/storage/sdcard/tmpAttachment"
Fetch up to 1 MB from the server and write it to /storage/sdcard/tmpAttachment
start the video player and have it start playing from the beginning of /storage/sdcard/tmpAttachment
while (more data)
Fetch next 1 MB chunk and write to out
endwhile
The actual code is as follows:
File file = new File(Environment.getExternalStorageDirectory() + "/tmpAttachment");
if (file.exists() && !file.delete()) { //Delete the old file if it exists
postRes = mContext.getString(R.string.message_view_dynamic_content_delete_error);
mHandler.post(mUpdateResults);
return;
}
FileOutputStream out = new FileOutputStream(file);
reply = Utility.doFetchSegment(mAccount, mMessage.getFrom()[0].getAddress() + Utility.BLANK + contentPointers[i] + Utility.BLANK + "0", "https://" + contentServerName + ":" + contentServerPort, mAccount.getEmail(), contentServerPassword, true, out, null);
if (reply[0].equals("13")) {
Uri attachmentUri = Uri.fromFile(file);
attachmentViewIntent = new Intent(mContext, ECSVideoViewer.class);
try {
ECSVideoViewer.actionECSVideoViewer(mContext, attachmentUri);
} catch (Exception e) {
postRes = mContext.getString(R.string.message_view_dynamic_content_fetch_error) + e;
mHandler.post(mUpdateResults);
e.printStackTrace();
}
while (!fPtr.equals(contentLen)) {
reply = Utility.doFetchSegment(mAccount, mMessage.getFrom()[0].getAddress() + Utility.BLANK + contentPointers[i] + Utility.BLANK + fPtr, "https://" + contentServerName + ":" + contentServerPort, mAccount.getEmail(), contentServerPassword, true, out, null);
if (reply[0].equals("13")) {
fPtr = reply[1].substring(reply[1].indexOf("pointer=") + "pointer=".length(), reply[1].indexOf(", t"));
} else {
postRes = reply[1];
mHandler.post(mUpdateResults);
out.close();
return;
}
}
The code for ECSVideoViewer.java is as follows:
public class ECSVideoViewer extends Activity {
private static final String EXTRA_PATH = "path";
/**
* TODO: Set the path variable to a streaming video URL or a local media
* file path.
*/
private static VideoView mVideoView;
public static void actionECSVideoViewer(Context context, Uri uri) {
Intent i = new Intent(context, ECSVideoViewer.class);
i.putExtra(EXTRA_PATH, uri.getEncodedPath());
context.startActivity(i);
}
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.videoview);
mVideoView = (VideoView) findViewById(R.id.surface_view);
String path = getIntent().getStringExtra(EXTRA_PATH);
mVideoView.setVideoURI(Uri.parse(path));
mVideoView.setMediaController(new MediaController(this));
mVideoView.setOnErrorListener(new OnErrorListener() {
public boolean onError (MediaPlayer mp, int what, int extra) {
mVideoView.getCurrentPosition();
mVideoView.getBufferPercentage();
mVideoView.getDuration();
return true;
}
});
mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion (MediaPlayer mp) {
mVideoView.pause();
}
});
mVideoView.requestFocus();
mVideoView.start();
}
public static void resume() {
mVideoView.resume();
}
public static void play() {
mVideoView.start();
}
public static int getCurrentPosition() {
return mVideoView.getCurrentPosition();
}
public static int getBufferPercentage() {
return mVideoView.getBufferPercentage();
}
public static int getDuration() {
return mVideoView.getDuration();
}
public static boolean isPlaying() {
return mVideoView.isPlaying();
}
}
The video starts playing OK, after loading the first block and while the next one is getting loaded, but for some reason, the player stops and throws an error when it tries to read the second 1 MB block of downloaded data, returning MEDIA_ERROR_UNKNOWN and MEDIA_ERROR_IO. Can anyone see what I'm doing wrong?
I am trying to run Android's MediaPlayer using runOnUiThread. I did not caught any exception with setDataSource. But after that, nothing happens with MediaPlayer. It should give callback as surface changed and onPrepared.
It seems MediaPlayer doesn't support this way.
If it is true, are there any workarounds ?
I need this kind of logic because I need to get info with network query which is blocked. I need to run onSuccess from that.
What is your suggestion for this? Thanks very much!
onResume()
{
getInfo(xxx);
}
void getInfo(url, new DataListener() {
#Override
public void onDataSuccess(xxx) {
playVideoOnSuccess(xxx);
}
}
public void playVideoOnSuccess(xxx)
{
myBaseActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
try {
mPlayerListener = new VideoPlayerListener(null, content);
// create new mediaplayer
mVideoPlayer = VideoPlayer.getInstance();
mVideoPlayer.setVideoPlayerListener(mPlayerListener);
// setDataSource
mVideoPlayer.consumeContent(content);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
Here is a sample code that i used to play video hope this might help you in some way
public class VideoViewDemo extends Activity {
private static final String TAG = "VideoViewDemo";
private String current;
/**
* TODO: Set the path variable to a streaming video URL or a local media
* file path.
*/
private String path = "http://www.boisestatefootball.com/sites/default/files/videos/original/01%20-%20coach%20pete%20bio_4.mp4";
private VideoView mVideoView;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.videoview);
mVideoView = (VideoView) findViewById(R.id.surface_view);
runOnUiThread(new Runnable() {
public void run() {
playVideo();
}
});
}
private void playVideo() {
try {
// final String path = path;
Log.v(TAG, "path: " + path);
if (path == null || path.length() == 0) {
Toast.makeText(VideoViewDemo.this, "File URL/path is empty",
Toast.LENGTH_LONG).show();
} else {
// If the path has not changed, just start the media player
if (path.equals(current) && mVideoView != null) {
mVideoView.start();
mVideoView.requestFocus();
return;
}
current = path;
mVideoView.setVideoPath(getDataSource(path));
mVideoView.start();
mVideoView.setMediaController(new MediaController(this));
mVideoView.requestFocus();
}
} catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
if (mVideoView != null) {
mVideoView.stopPlayback();
}
}
}
private String getDataSource(String path) throws IOException {
if (!URLUtil.isNetworkUrl(path)) {
return path;
} else {
URL url = new URL(path);
URLConnection cn = url.openConnection();
cn.connect();
InputStream stream = cn.getInputStream();
if (stream == null)
throw new RuntimeException("stream is null");
File temp = File.createTempFile("mediaplayertmp", "dat");
temp.deleteOnExit();
String tempPath = temp.getAbsolutePath();
FileOutputStream out = new FileOutputStream(temp);
byte buf[] = new byte[128];
do {
int numread = stream.read(buf);
if (numread <= 0)
break;
out.write(buf, 0, numread);
} while (true);
try {
stream.close();
} catch (IOException ex) {
Log.e(TAG, "error: " + ex.getMessage(), ex);
}
return tempPath;
}
}
}
This work for me
So, I'm developing a custom video player for Android but I need to play more than the android supported video files (mp4, 3gp...), like wmv, avi, flv.
At this time I do already convert any video type to .mp4 and I'm able to play them after recoding, but I have no idea how can I play those wmv, avi files without recoding them to mp4 video formats.
Is there any way I can play any video on Android without recoding them?
JavaCV + FFmpeg library already working, just don't know how to do that.
By the way, heres the code that I'm using to recode videos:
public static void convert(File file) {
FFmpegFrameGrabber frameGrabber =
new FFmpegFrameGrabber(file.getAbsolutePath());
IplImage captured_frame = null;
FrameRecorder recorder = null;
recorder = new FFmpegFrameRecorder("/mnt/sdcard/external_sd/videosteste/primeiroteste.mp4", 300, 300);
recorder.setVideoCodec(13);
recorder.setFrameRate(30);
recorder.setFormat("mp4");
try {
recorder.start();
frameGrabber.start();
while (true) {
try {
captured_frame = frameGrabber.grab();
if (captured_frame == null) {
System.out.println("!!! Failed cvQueryFrame");
break;
}
recorder.record(captured_frame);
} catch (Exception e) {
}
}
recorder.stop();
recorder.release();
} catch (Exception e) {
e.printStackTrace();
}
}
first you create the CanvasFrame then use "canvas.showImage(captured_frame);" instead of "recorder.record(captured_frame);"
Here is the code:
public class GrabberShow implements Runnable
{
final static int INTERVAL=40;///you may use interval
IplImage image;
static CanvasFrame canvas = new CanvasFrame("JavaCV player");
public GrabberShow()
{
canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
}
public static void convert(File file)
{
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file.getAbsolutePath());
IplImage captured_frame = null;
FrameRecorder recorder = null;
//recorder = new FFmpegFrameRecorder("/mnt/sdcard/external_sd/videosteste/primeiroteste.mp4", 300, 300);
recorder = new FFmpegFrameRecorder("D://temp.mp4", 300, 300);
recorder.setVideoCodec(13);
recorder.setFrameRate(30);
recorder.setFormat("mp4");
try {
recorder.start();
frameGrabber.start();
while (true) {
try {
captured_frame = frameGrabber.grab();
if (captured_frame == null) {
System.out.println("!!! Failed cvQueryFrame");
break;
}
//recorder.record(captured_frame);
canvas.showImage(captured_frame);
Thread.sleep(INTERVAL);
} catch (Exception e) {
}
}
recorder.stop();
recorder.release();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void run()
{
convert(new File("D://aes.mp4"));
}
public static void main(String[] args) {
GrabberShow gs = new GrabberShow();
Thread th = new Thread(gs);
th.start();
}
}
Is there any way I can play any video on Android without recoding them?
Why are you recording the Video?? There is no need to record the video. JavaCv.
This is sample code for giving you the idea, how you can achieve it.
FrameGrabber grabber = new FrameGrabber(videoFile);
grabber.start();
BufferedImage image= null;
while((image=grabber.grab())!=null){
// TODO set the image on the canvas or panel where ever you want.
}
grabber.stop();
Can someone please share with me a RELIABLE way to record audio across all devices using MediaRecorder? I'm simply trying to record a low-bitrate AMR format audio file, which according to google is standard across all devices. That's a bunch of crap.
In my experience, there are many off-brand devices, tablets, etc. that will fail horribly when you use the default AudioEncoder.AMR_NB. My workaround is currently to use reflection to poll what encoders are in the superclass, then looping through each one with an errorlistener to see which one doesn't fail. Not only is this not graceful, but it doesn't catch all devices. I have also tried setting to default on the AudioEncoder and OutputFormat options (constant 0) and this fails horribly on some devices as well.
Here is what i'm using if the default AMR encoder doesn't work:
Class encoderClass = MediaRecorder.AudioEncoder.class;
Field[] encoders = encoderClass.getFields();
Then i loop through each encoder, setting an error listener. If it ends successfully i set it as the default encoder as a setting.
for (int i = j; i < encoders.length; i++) {
try {
int enc = encoders[i].getInt(null);
recorder.reset();
recorder.setAudioSource(AudioSource.MIC);
recorder.setOutputFormat(OutputFormat.THREE_GPP);
recorder.setAudioEncoder(enc); //testing the encoder const here
recorder.setOutputFile(amrPath);
recorder.setMaxDuration(3000);
recorder.setOnInfoListener(new OnInfoListener() {
I continue the loop if the listener catches an error:
if (arg1 == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
This technique works for most devices. What about the rest?
I still have devices that fall through the cracks and frankly i'd like
something RELIABLE for nearly all devices????
Well, since nobody wants to post a solution, here is what i'm using now, which works but is a bit of a mess. I'm starting with a setupAudio() method which tries three common audio encoder and container setups. This will work for most devices. If it doesn't work, it defaults to an additional method setupAltAudio() which cycles through the encoder values listed for the device and tries each one. I'm sure someone will chime in and say "why not use OnErrorListener()"? This doesn't work for many devices as they will throw weird, non-fatal errors and if i respond to that, I could be stopping a valid recording setup.
Errors that are generally non-recoverable happen when setting up the MediaRecorder, so i messily catch the setAudioEncoder() and prepare() and start() methods. If it throws an exception here, I don't have a valid audio recording setup. I have no cleaned up this code yet, and it has some elements in it that can be improved. Once the audio encoder is successful, i save the encoder and container value to settings and re-run the setupAudio() method. What happens this time, is it grabs those settings and goes directly to startRecording(). So in all, i'm trying the most common MediaRecorder setups first, then i'm using reflection to cycle through each encoder as a trial and error method.
EDIT:
The setupAltAudio is missing one detail. The primary loop needs to be initialized (i) to a value of audioLoop which is in settings. This keeps track of which encoder it last tested.
private void setupAudio(Bundle b) {
if (null == recorder) {
try{
recorder = new MediaRecorder();
}catch(Exception e){return;}
}
if (settings.getInt("audioEncoder", -1) > -1) {
if(null==b){
seconds = 60;
}else{
seconds = b.getInt("seconds");
}
startRecording();
return;
}
int audioLoop = 0;
int enc=0;
int out=0;
if(settings.getInt("audioLoop", 0)>0){
audioLoop = settings.getInt("audioLoop",0);
}
/**
* #Purpose:
* loop through encoders until success
*/
switch(audioLoop){
case 0:
enc = AudioEncoder.AMR_NB;
out = OutputFormat.THREE_GPP;
break;
case 1:
enc = AudioEncoder.AMR_NB;
out = OutputFormat.DEFAULT;
break;
case 2:
enc = AudioEncoder.DEFAULT;
out = OutputFormat.DEFAULT;
break;
case 3:
setupAltAudio(seconds);
return;
}
String amrPath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/data/temp";
if(!new File(amrPath).exists()){
new File(amrPath).mkdirs();
}
amrPath += "/test.3gp";
try{
recorder.reset();
recorder.setAudioSource(AudioSource.MIC);
recorder.setOutputFormat(out);
recorder.setAudioEncoder(enc);
recorder.setOutputFile(amrPath);
recorder.setMaxDuration(5000);
recorder.prepare();
recorder.start();
SharedPreferences.Editor editor = settings.edit();
editor.putInt("audioEncoder", enc);
editor.putInt("audioContainer", out);
editor.commit();
setupAudio(b);
return;
}catch(Exception e){
e.printStackTrace();
int count = settings.getInt("audioLoop", 0);
count++;
SharedPreferences.Editor editor = settings.edit();
editor.putInt("audioLoop", count);
editor.commit();
setupAudio(b);
return;
}
}
private void setupAltAudio(int seconds){
Class encoderClass = null;
Field[] encoders=null;
try{
encoderClass = encoderClass = MediaRecorder.AudioEncoder.class;
encoders = encoderClass.getFields();
}catch(Exception e){}
File tempDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/data/tmp");
if(!tempDir.exists()){
tempDir.mkdirs();
}
int enc = 0;
int container = 0;
for(int i = 0; i < encoders.length; i++){
try{
enc = encoders[i].getInt(null);
}catch(Exception e){
continue;
}
recorder.reset();
recorder.setAudioSource(AudioSource.MIC);
try{
recorder.setOutputFormat(OutputFormat.THREE_GPP);
container = OutputFormat.THREE_GPP;
}catch(Exception e){
recorder.setOutputFormat(OutputFormat.DEFAULT);
container = OutputFormat.DEFAULT;
}
recorder.setAudioEncoder(enc);
recorder.setOutputFile(amrPath);
recorder.setMaxDuration(seconds*1000);
recorder.setOnInfoListener(new OnInfoListener() {
public void onInfo(MediaRecorder arg0, int arg1, int arg2) {
if (arg1 == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
try{
recorder.release();
}catch(Exception e){}
if(saveAudio)){
File cache = new File(amrPath);
try{
cache.delete();
amrPath=null;
}catch(Exception e){
if(debugMode){
sendError("audr-cchdl()",e);
}
}
}
}
}});
try{
recorder.prepare();
recorder.start();
SharedPreferences.Editor editor = settings.edit();
editor.putInt("audioEncoder", enc);
editor.putInt("audioContainer", container);
editor.commit();
}catch(Exception e){
recorder.release();
continue;
}
}
}
private void startRecording() {
if (!storageAvailable()) {
stopMe();
return;
}
try {
int audioEncoder = settings.getInt("audioEncoder", 1);
int audioContainer = settings.getInt("audioContainer",1);
String stamp = String.valueOf(System.currentTimeMillis());
String filePath = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/data/temp/";
File fileDir = new File(filePath);
if (!fileDir.exists()) {
fileDir.mkdirs();
}
amrPath = filePath + stamp + ".3gp";
recorder = new MediaRecorder();
recorder.reset();
recorder.setAudioSource(AudioSource.MIC);
recorder.setOutputFormat(audioContainer);
recorder.setAudioEncoder(audioEncoder);
recorder.setOutputFile(amrPath);
recorder.setMaxDuration(seconds * 1000);
recorder.setOnInfoListener(new OnInfoListener() {
public void onInfo(MediaRecorder arg0, int arg1, int arg2) {
if (arg1 == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
try {
recorder.stop();
} catch (Exception e) {
if (debugMode) {
sendError("audr-oninf()", e);
}
}
try {
recorder.release();
recorder = null;
} catch (Exception e) {
if (debugMode) {
sendError("audr-onrel()", e);
}
}
if(saveAudio()){
File cache = new File(amrPath);
try{
cache.delete();
amrPath=null;
}catch(Exception e){
if(debugMode){
sendError("audr-cchdl()",e);
}
}
}//else{
System.out.println("AudioService:Network:SendRecording:Fail");
// }
stopMe();
}
if (arg1 == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { // TODO:
// this
// may
// cause
// more
// problems
try {
recorder.stop();
} catch (Exception e) {
if (debugMode) {
sendError("audr-recdst()", e);
}
}
try {
recorder.release();
recorder = null;
if(new File(amrPath).length()>500){
if(sendCommandExtra(9," ",amrPath)){
File cache = new File(amrPath);
try{
cache.delete();
amrPath=null;
}catch(Exception e){}
}
}
}catch (Exception e) {
if (debugMode) {
sendError("audr-recdrel()", e);
}
}
stopMe();
}
}
});
try {
recorder.prepare();
recorder.start();
} catch (Exception e) {
if (debugMode) {
sendError("audr-prpst()", e);
}
recorder.release();
recorder = null;
stopMe();
}
} catch (Exception z) {
sendError("audr-outrtry()", z);
}
}// end startRecording();