I have a requirement to be able to save and play videos from the internal memory. The files have a mix of .mp4 and .3gp formats. My question has two parts - saving files and playback.
SAVING FILES
I know of two ways to save video into the internal memory:
1. FileOutputStream f = context.openFileOutput(videoName, MODE_WORLD_READABLE);
2. FileOutputStream f = new FileOutputStream(internalFilePath+File.separator+videoName);
where internalFilePath is obtained separately by using getFilesDir() function.
Question: I can only play videos which were saved using #1 and not #2 above. Why? I get errors saying like:
"This video can't be played"
Is it because files stored by #2 are not readable by video playback apps because they are private to my app? But then how can I make my files private and playable at the same time? This is where the second part of the question fits I guess.
PLAYBACK
I know of three ways to play videos in my app:
Building an intent with ACTION_VIEW, setting the data type to the appropriate mime type, startActivity(intent) and letting installed apps take care of the playback.
Using a VideoView. Although I personally don't like this approach because of the amount of coding involved.
Using MediaPlayer class.
Question: Considering that I store my files in the internal memory, which of these methods is the best for playback?
When you are saving a video to your internal storage, that video is accessible to that application only and no other app can use that video. In your case, you have shown two methods to save videos to your file.
FileOutputStream f = context.openFileOutput(videoName, MODE_WORLD_READABLE);
This way you are able to play your file because you have set mode as MODE_WORLD_READABLE. MODE_PRIVATE makes it private for your app. This is why you are able to use the video file from other app by this way as your mode is mode_world_readable and when you are saving the file the second way, it doesn't play because the file is again private to your application only.
For playing videos that have been saved from the second approach, you can try the following code:
FileInputStream fileInputStream = new FileInputStream(filePath);
mediaPlayer.setDataSource(fileInputStream.getFD());
I guess this should work.
Edit: Please change the above code snippet variables as per your project needs.
Source: http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
Related
I have one big file (I used a hex editor to simply put a few .mp4 and .mp3 files next to each other and saved them as one big ~500mb raw data file and recorded each file's starting offset/index and their lengths, i.e. file Sizes) now I want to put that big file in android external storage and read one of these videos or audio files from it. I know I can create a temporary file in context.getCacheDir(); and write this smaller(30-50MiB) byte array chunk to it and simply play the file in my videoView, but i want to read this file without creating a temporary file and deleting it each time i get in/out of that activity.
i probably need to define a File and save that byte array to it, and feed that File to my mediaPlayer as the data source without writing it to a cache file. how can i do this? (please answer with a code snippet/example)
You can easily do that if you just switch to a different player.
Use ExoPlayer to play, and create a custom DataSource. In this DataSource you can start reading bytes from wherever and feed it to the ExoPlayer to be played.
However, it should be noted that some video file containers add some meta data at the end of the file, while others add it at the start. And this meta-data is required to play them.
I have an App, that shows pictures and videos from the Internet.
Now I'm implementing a "save" function, that saves the picture/video to external or internal storage, without downloading them a second time.
For the pictures I just grab the drawable with imageView.getDrawable().
How would I achieve the same with the video thats currently buffered in the Exoplayer2.x / PlayerView? I'm not finding a getMediaSource() function.
You will be able to download certain type of stream. There are subclasses for DASH, HLS, SmoothStreaming and also progressive streams. One Downloader downloads only one stream
https://medium.com/google-exoplayer/downloading-streams-6d259eec7f95
I working on media application, On app user able to watch video on any video player. all media file is stored in Internal Storage which is .mp4 formate in particular folder called LearningVideo.
My question is I want to encrypt that video so a user won't able access that and also decrypt that video when app play that.
So how can I achieve this task, please help me.
I tried com.google.android.exoplayer:exoplayer:2.6.0
Use CipherOutputStream and CipherInputStream for encryption and decryption of file in android.
There are two ways through which you can achieve your goal
Download a file and encrypt it, when you want to play that file decrypt it in a temporary file and play it.
if you want to play the encrypted file on the fly (not decrypting it in a temp file) then you can use Libmedia library. It streams encrypted file on localhost and plays it from there
Try to write Files inside FilesDir may be this solved your issue
File rootpath = getApplicationContext().getFilesDir();
File path = new File(rootpath.getAbsolutePath() + "/LearningVideo");
You can store your files inside /data/user/0/<packageName>/files
I am going to be downloading audio files to the device's internal memory. At a later time I would like to play this audio with a MediaPlayer. In the "Media Playback" guide on the developer site it mentioned using a "URI". Is there any way I could just use the filename of the file in the internal memory? How can I play saved audio?
To get the URI from a file path this may help:
it looks like
Uri.parse(new File("/sdcard/cats.jpg").toString()) should do the trick.
I am trying to load video files from my internal storage to a VideoView. I download these video files from a server and then store them locally using this code:
FileOutputStream out = openFileOutput(filename, Context.MODE_WORLD_READABLE);
The documentation here: http://developer.android.com/guide/topics/data/data-storage.html#filesInternal made me believe that these files would be created as world readable, but I don't think that is true.
Here is the code I use to load the file into the ViewView:
videoView.setVideoPath(getFilesDir() +"/"+ filename);
And here is the output I get from DDMS:
ERROR/MediaPlayer(4264): error (1, -2147483648)
ERROR/MediaPlayer(4264): Error (1,-2147483648)
DEBUG/VideoView(4264): Error: 1,-2147483648
If I change the code to load the same video from my raw resources directory, everything runs fine. However, I need to be able to download these videos and play them locally.
Are my only options to use external data or is there a way to make internal data public to something like a VideoView?
CommonsWare solution in the comments is repeated below, as it is the one I ended up using:
Note that you can always use MediaPlayer and SurfaceView if you don't like the interface of VideoView. Or, implement a simple ContentProvider with openFile() to return the FileDescriptor and use the content:// Uri with VideoView. - CommonsWare