I have a videoView and loading video's from a remote server.
I'm getting random error as per below.
Problem is, it works sometimes and sometimes it doesn't.
videoView.setVideoURI(Uri.parse(Constants.API_IMAGE_HOST + "ads/video/" + this.adVideoObject.ad_videos_id + ".mp4"));
the error i get is:
MediaPlayer﹕ setDataSource IOException happend :
java.io.FileNotFoundException: No content provider:
Again, I get it sometimes but not always.
Ok, as I have mentioned in numerous other posts about VideoView, DONT USE IT! I am a professional Android developer that develops apps that are all about video playback and in my experience, VideoView is entirely unreliable and is very difficult if not impossible to get it to behave correctly across multiple devices. I would strongly suggest for you to look into the ExoPlayer library if playback is at all important to your app. It is harder to setup but the performance and reliability improvements are soo worth it.
I apologize that this does not explicitly answer your question. However I believe that you will find the ExoPlayer library a pure joy to work with over VideoView or MediaPlayer.
The error
D/MediaPlayer: setDataSource IOException | SecurityException happend :
java.io.FileNotFoundException: No content provider: http://192.168.1.114:1376/%25/F885C5CE27F16C4D64588D48A3001A1B/9.mp4
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1137)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:988)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:911)
at android.media.MediaPlayer.attemptDataSource(MediaPlayer.java:1102)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1093)
Is part of the normal flow of the VideoView setDataSource. It tries to open the file locally, and then moves onto loading remotely.
Typically there will be a further error message which explains the actual failure.
In my case, it was getDuration being called in the incorrect state. So look further down the logs, and check that you are following the state diagram in the documents and ensuring that the API is called only when the view is in the correct state
Related
I am trying to reproduce MPEG DASH, HLS and HSS(HTTP SmoothStreaming) streams by using modified sample applications provided by Google, but for now, only DASH is working.
I use:
https://github.com/googlecast/cast-custom-receiver
and
https://github.com/googlecast/CastVideos-android
As i see here https://developers.google.com/cast/docs/player?hl=en all protocols (HSS, HLS, DASH) should work without problems.
When i try to stream HSS and HLS i get this in Sample Media Receiver HUD:
Media Element State: "Error" (or "Abort")
.
.
.
Host State: "Fatal Error: code = 1"
Does anyone know what that error represents?
Also, sometimes i get this "Fatal Error: code = 0".
//UPDATE
I get this error when i try to cast HSS:
[2648.568s] [cast.receiver.MediaManager] Load metadata error cast_receiver.js:19
and the link is :
http://video3.smoothhd.com/ondemand/Turner_Sports_PGA.ism/Manifest
//UPDATE
HLS is working now. Problem is solved by setting CORS headers.
I don't know what HSS is and we don't mention HSS as a supported protocol either, nor we claim we support "all" protocols. We have listed the supported protocols/variations in the link that you have mentioned.
Problem was with codecs... I used streams encoded with VP1 video and WMAP audio codecs, so there were many errors. That is the reason for getting all those LOAD METADATA ERRORs.
And for CORS, you can use this: https://github.com/TOMODOcom/TOMODOkorz
Works like a charm :)
I've finished developing a game, but it's very annoying that sometimes (yes, only sometimes!) when I open it, it fails, and I can see in logcat this error: java.io.IOException: Prepare failed.: status=0x80000000.
It's very weird because it's a local file (2MB mp3 file), and I don't know why it shows a IOException. And only sometimes, not always...
EDIT: It seems that is related with proguard, because it only happens with release version...
I finally solved it.
It happened because my MediaPlayer variables were static, so when I restart the app I was creating more MediaPlayers without releasing previous ones, and there is a limit of 8 (at least in Android 2.3.6, where I tested it). Calling mediaPlayer.release() (if mediaPlayer != null, of course) it's solved.
Hope it helps someone.
I have get the same issue here. (may 2021)
And when I find on internet I see some answer about this thing. They said that when mediaPlayer prepare datasource and it can not read the end char so it return IOException Prepare failed. So the way they resolved that is convert to new file with difference type (wav, mp4, mp3,...). Hope can help anyone on this issue.
I have to modify the Http Live Streaming implementation of Android Media Player.
The implementation is under the stagefright library
http://androidxref.com/4.0.4/xref/frameworks/base/media/libstagefright/httplive/LiveDataSource.cpp
I think these library will compile to a libstagefright.so which should be part of the Android system.
My question is if I make some changes to this library and compile a new libstagefright.so.
If I load this new libstagefright.so in my new application and call up the media player, will it use the code in my new libstagefright.so?
You will not be able to replace the original library, since when you try to loadLibrary it will load the library from within /system/lib. So unless you replace that (which is not possible on unrooted devices), you won't be able to load your custom code.
https://github.com/android/platform_system_core/blob/66ed50af6870210ce013a5588a688434a5d48ee9/rootdir/init.environ.rc.in sets the LD_LIBRARY_PATH by default. And loads it from these paths if available. If not, then your application's lib directory will be searched; but not the other way around.
I tried this with libwebkit.so in the past on various mainstream devices and haven't had any luck getting it to load instead of the one in /system/lib.
You can learn more by looking at:
doLoad from here https://android.googlesource.com/platform/libcore/+/41d00b744b7772f9302fdb94dddadb165b951220/luni/src/main/java/java/lang/Runtime.java
findLibrary here http://developer.android.com/reference/dalvik/system/BaseDexClassLoader.html#findLibrary(java.lang.String)
I'm pretty sure you can't replace the default class loader either for security reasons.
What you can do, though, is a straightforward fork the Media Player and have it load your modified libstagefright-modified.so. There could be other solutions, haven't looked at Media Player's code.
Knowing that all you want to do is parse the data before it gets to the MediaPlayer, I suggest not trying to alter the Android libraries. As soulseekah mentioned, it's not going to work without a rooted device. There are other options, although they both have drawbacks.
1) If you are only targeting recent versions (4.2 or later, I believe), you can take a look at new classes added to the android.media package, like MediaExtractor and MediaCodec. I'm not greatly familiar with those because they aren't available on the hardware with which I work, but they could be useful in getting to the raw data. Here is a decent sample of using them to play video. The drawback is those classes aren't available in earlier versions.
2) The other option is to put a local proxy on the device. Connect the MediaPlayer to the proxy and make the request to the media server yourself. See my answer here for a little more info on that. With a proxy, you will see all the data that comes through, giving you a chance to parse the ID3 tags. There is the drawback that you will have to parse the TS packets to put together an elementary stream (essentially doing the demuxer's job), but it will work with any version of Android. TS streams aren't difficult to disassemble, and ID3 tags aren't time consuming to parse, so I think this is a reasonable approach.
I am working on an android project which needs to create and write files rapidly. I am using ndk for this purpose and found that fopen() call takes uncertain amount of time, from minimum ~30ms to several seconds whening running from the main thread. After opening the file, I then need to compute some results, store results into the opened file and then close it.
I am trying to put it into another thread but not sure if it helps at all and how to handle scheduling issue if it does. I am also thinking about possibly opening many of those file descriptors at the beginning of the application and maintain a pool of those through the applcation. Anyone helping to point to the right direction?
It sounds like you are trying to go very low level.
Have you considered using the open() write() and close() System calls. The c-library fopen calls do some nice things for you such as buffering, but the system calls are likely to be faster. You will have to profile, but I think you will see lower latency.
int fd = open("myfilepath",O_WRONLY|O_CREAT);
write(fd,myData, myDataSize);
close(fd);
You will find more info here.
http://www.tutorialspoint.com/unix_system_calls/open.htm
I can successfully listen to an audio stream with the MediaPlayer interface, but how can I get properties of the stream like the current bit rate, or the stream text (lots of streams like on line radios include the currently playing track)?
I tried to find this information but couldn't, if these things are possibly is there a list somewhere on the android dev site where the various available 'properties' are listed?
First, the Android DEV site is the site with all class information - but sometimes hard to find what you need. In that case, checking the java source of the class can be quite helpful.
From a quick look into the SDK, there is an onInfoListener interface, which you can implement in a class extending MediaPlayer. That needs you to have public boolean onInfo(MediaPlayer mp, int what, int extra) implemented.
http://developer.android.com/reference/android/media/MediaPlayer.OnInfoListener.html states there is a what=MEDIA_INFO_METADATA_UPDATE.
But - checking google for that would give the idea that this never gets called :-/
So eventually you are on your own with that...
I could be making this harder than it needs to be, but you can decode a frame of the Stream with Jlayer or some other MP3 decoding library to get the info you are looking for. Not sure if there is a way to do this with just the Android sdk.
If your stream is a shoutcast/icecast stream then you can use the utility class at http://code.google.com/p/streamscraper/ to extract the metadata including the song title.
Alternatively, you can build your own metadata extractor. Take a look at http://www.smackfu.com/stuff/programming/shoutcast.html for more info.