My app has a photo gallery that displays a constant list of images. I need to add one video to that list (just one, provided by me). This video is inside an expansion file. I would like to let the user decide the video player he wants to use to play the video. So I went for the intent approach:
public void playVideo(View view){
Intent videoint = new Intent(Intent.ACTION_VIEW);
Uri uri = CustomAPEZProvider.buildUri("test.3gp");
Log.d("TEST", uri.toString());
videoint.setDataAndType(uri, "video/*");
startActivity(videoint);
}
My CustomAPEZProvider is the following:
public class CustomAPEZProvider extends APEZProvider {
private static final String AUTHORITY = "com.myapp.package.provider";
#Override
public String getAuthority() {
return AUTHORITY;
}
public static Uri buildUri(String path) {
StringBuilder contentPath = new StringBuilder("content://");
contentPath.append(AUTHORITY);
contentPath.append(File.separator);
contentPath.append(path);
return Uri.parse(contentPath.toString());
}
}
Also, I added this to my manifest:
<provider android:name="com.myapp.package.CustomAPEZProvider"
android:authorities="com.myapp.package.provider" >
android:exported="true"
android:multiprocess="true">
<meta-data
android:name="mainVersion"
android:value="4"/>
</provider>
The provider has this meta-data because the expansion file version differs from the apps version code.
I understand that the file is being found, but the video players are not able to play it. They are launching the can't play this video window (and no errors). I tested it on many devices and with different kinds of videos. The 3gp video I'm using to test can be played just fine from the phone's native gallery.
Line 3 on the playVideo method is printing this
content://com.myapp.package.provider/test.3gp
This is correct, right?
The expansion file has no folders, files are just thrown at root.
Also, I actually need to play this test.3gp video from the patch expansion file. Will there be any difference in that case? I'm eliminating this obstacle for now. I know I should add it to the provider's meta-data.
Some extra information: the expansion file has several audio files that I'm being able to play using a MediaPlayer without any issues. Of course, this is different because in that case I'm doing it by getting an AssetFileDescriptor to the file inside the obb expansion file, whereas with the video I need an Uri, which changes everything.
I read lots of questions with similar problems, but they were not helpful. Does anyone had the same problem?
Workarounds are also welcome. For example, I could accept to use a VideoView if needed.
UPDATE
I've just realised that the video player is not working, even if the file is a resource (inside drawable, raw, or whatever). I did manage to play the video with the code below:
public void playVideo(View view){
Uri uri = CustomAPEZProvider.buildUri("test.3gp");
getWindow().setFormat(PixelFormat.TRANSLUCENT);
VideoView videoHolder = new VideoView(this);
videoHolder.setMediaController(new MediaController(this));
videoHolder.setVideoURI(uri);
setContentView(videoHolder);
videoHolder.start();
}
But this is not exactly what I want, I'd really like to allow the user to choose the video player of his preference. Mainly because I want to free myself from the responsibility to code a nice-to-look-at video player.
I don't think the problem lies anywhere in your code. Or, if it does, it's not your biggest problem.
I think your biggest problem is using a 3GP file. That format is not supported by all devices. You're better off with an MP4. And even then, make sure that it's encoded with a CODEC that all Android devices understand.
I had the same problem (video played without problem with native gallery, but not through intent). How the problem is solved is to add the following line to manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and give the permission to the installed app.
Related
My project includes two modules, one main module with all the XML, Kotlin files, and images, and another with all the video files. I had to do this because my app has like 20 videos and it exceeds that 150 MB cap that is put on the app bundles. Anyway, I have am trying to play a video through a video view, and it worked before by just finding the filepath. Now, I'm not sure how to access the video in another module, and when I try to get the filepath it can't find it. I've already set up the dependencies, so I don't know what the issue is.
Here is an example of what I had before I moved the videos into the new module, and this worked:
val intent = Intent(requireActivity(), WatchActivity::class.java)
intent.putExtra("filePath", "android.resource://${requireActivity().packageName}/${R.raw.addeventvideo}")
requireActivity().startActivity(intent)
If you're wondering, that code is inside of an onClickListener for a button so that it opens a new activity with a videoview that plays the video with the filepath I pass into the intent.
Thanks for any help with this.
I want to build an android app. Basically, I have a Web site where I have a lot of music into categories and from there you can listen to it or download. I want to use my app to have a mobile view of my site, and I know how to do it with android studio, there are just some things I need to change. Anyway, I want the app background/style to be different, and I want everytime I add a new category to my site, to be added to my app to. At first, I was wanting to make a button for every category, but I realised it won t work.
Anyway, in the app, the first thing that you ll see are the categories, then if you click on one of them, you will se a list of ringtone, and if you click on a ringtone, you will have 4 options : set as ringtone, set as notification, set as alarm. I know what s the code for this things, what I do not understand is where to place it, because I want my app to use the music from my site, not to have a music as an asset and then set it (that s the way I know how to do it). I know is redundant, but I am a teenager:)). I know how to build an app that can set a ringtone, I do not know how to do it for hundreds of ringtones that I do not have as an asset.
Some ideas please ? Maybe a video oor something to read
For playing a ringtone for preview purposes you have two options:
You can either stream it via the MediaPlayer class.
which is done like this:
String url = "http://your-path";
MediaPlayer mPlayer = new MediaPlayer();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(url);
mPlayer.prepare();
mPlayer.start();
but keep in mind that prepare() method might take a while and it blocks UI thread. you need to use prepareAsync() and set a listener for it when prepared.
mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){
#Override
public void onPrepared(MediaPlayer mp) {
mPlayer.start();
}
});
but if you'd also like to download it before playing it you can use this library AQuery. If you are new to android it can really help you to easily make http calls and downloads asynchronously. It is initiated and used as follows:
AQuery aq = new AQuery(context);
File ringtoneFileToDownload = new File("http://path/to/your/online/ringtone");
aq.download(url, ringtoneFileToDownload, new AjaxCallback<File>(){
#Override
public void callback(String url, File file, AjaxStatus status) {
//method is called when the download is finished
//and the file parameter is the file downloaded
//which you can play as above with the MediaPlayer class
}
});
you can use the above method to download it to the device and keep them local.
As the last thing don't forget to add the required permissions in the manifest file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I was creating a simple app which stream videos from net and I made it but now I want to change the code so that I can play video files from my SDCard
original code:
Uri vidFile = Uri.parse("MY SITE HERE");
VideoView videoView = (VideoView) findViewById(R.id.VideoView);
videoView.setVideoURI(vidFile);
videoView.setMediaController(new MediaController(this));
videoView.start();
So please help me with changing the code so that it can play videos from my mobile memory card.
The videoView.setVideoURI(vidFile); method needs to be replaced by the videoView.setVideoPath(path); method.
Here path specifies the path of the video file on the SDCARD.
This path can be easily retrieved using the MediaStore.Video.Media.DATA property of that video file or by just entering the songpath statically as /sdcard/songname.
Uri vidFile = Uri.parse(
Environment.getExternalStorageDirectory().getAbsolutePath()+"filename");
...
the rest of the code will be same.
In place of
videoView.setVideoUri(vidFile)
use
videoView.setVideoPath("/sdcard/SONG.").
Let me know.
these links may help you:
Playing 3gp video in SD card of Android
how-play-video-and-audio-android
Using VideoView to play mp4 from sdcard
I also tried your code and got same error message but when I tried with video path with no blank space in path or name, it worked well. Just give it a try.
e.g,
file path "/mnt/sdcard/Movies/Long Drive Song - Khiladi 786 ft. Akshay Kumar_Asin-YouTube.mp4"
gave the error but file path "/mnt/sdcard/Movies/Khiladi.mp4" worked well.
I know is is old but if it can help. add this to your manifest
<uses-permission android:name="com.android.externalstorage.ExternalStorageProvider"/>
I am trying to play a video in android emulator
I have the video in my assets folder as well as the raw folder
But after doing some research still i cant play video in my emulator
i am working on android 2.1
My video format is mp4 so i don't think that should be a problem
Could anyone just give me an example code so that i can understand a bit more?
The problem is that the VideoView that I need to display the Video will take only a URI or a File path to point to the Video.
If I save the video in the raw or assets folder I can only get an input stream or a file descriptor and it seems nothing of that can be used to initialize the VideoView.
Update
I took a closer look at the MediaPlayer example and tried to start a MediaPlayer with a FileDescriptor to the assets files as in the code below:
SurfaceView videoView = (SurfaceView) findViewById(gettingStarted)
SurfaceHolder holder = videoView.getHolder();
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
final MediaPlayer player = new MediaPlayer();
player.setDisplay(holder);
player.setDataSource(getAssets().openFd(fileName).getFileDescriptor());
player.prepareAsync();
player.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
Now I get a the following exception:
java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed
It seems there is no other way then copying the file to the sdcard on startup and that seems like a waste of time and memory.
## Perfectly Working since Android 1.6 ##
getWindow().setFormat(PixelFormat.TRANSLUCENT);
VideoView videoHolder = new VideoView(this);
//if you want the controls to appear
videoHolder.setMediaController(new MediaController(this));
Uri video = getUriFromRawFile(context, R.raw.your_raw_file);
//if your file is named sherif.mp4 and placed in /raw
//use R.raw.sherif
videoHolder.setVideoURI(video);
setContentView(videoHolder);
videoHolder.start();
And then
public static Uri getUriFromRawFile(Context context, #ResRaw int rawResourceId) {
return Uri.Builder()
.scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
.authority(context.getPackageName())
.path(String.valueOf(rawResourceId))
.build();
}
## Check complete tutorial ##
String UrlPath="android.resource://"+getPackageName()+"/"+R.raw.ur file name;
videocontainer.setVideoURI(Uri.parse(UrlPath));
videocontainer.start();
where videocontainer of type videoview.
Try:
AssetFileDescriptor afd = getAssets().openFd(fileName);
player.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(), afd.getLength());
PlayVideoActivity.java:
public class PlayVideoActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_video);
VideoView videoView = (VideoView) findViewById(R.id.video_view);
MediaController mediaController = new MediaController(this);
mediaController.setAnchorView(videoView);
videoView.setMediaController(mediaController);
videoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.documentariesandyou));
videoView.start();
}
}
activity_play_video.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<VideoView
android:id="#+id/video_view"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</VideoView>
</LinearLayout>
If I remember well, I had the same kind of issue when loading stuff from the asset folder but with a database. It seems that the stuff in your asset folder can have 2 stats : compressed or not.
If it is compressed, then you are allowed 1 Mo of memory to uncompress it, otherwise you will get this kind of exception. There are several bug reports about that because the documentation is not clear. So if you still want to to use your format, you have to either use an uncompressed version, or give an extension like .mp3 or .png to your file. I know it's a bit crazy but I load a database with a .mp3 extension and it works perfectly fine. This other solution is to package your application with a special option to tell it not to compress certain extension. But then you need to build your app manually and add "zip -0" option.
The advantage of an uncompressed assest is that the phase of zip-align before publication of an application will align the data correctly so that when loaded in memory it can be directly mapped.
So, solutions :
change the extension of the file to .mp3 or .png and see if it works
build your app manually and use the zip-0 option
Did you try to put manually Video on SDCard and try to play video store on SDCard ?
If it's working you can find the way to copy from Raw to SDcard here :
android-copy-rawfile-to-sdcard-video-mp4.
I found it :
Uri raw_uri = Uri.parse(<package_name>/+R.raw.<video_file_name>);
Personnaly Android found the resource, but can't play it for now. My file is a .m4v
VideoView myVideo = (VideoView) rootView.findViewById(R.id.definition_video_view);
//Set video name (no extension)
String myVideoName = "my_video";
//Set app package
String myAppPackage = "com.myapp";
//Get video URI from raw directory
Uri myVideoUri = Uri.parse("android.resource://"+myAppPackage+"/raw/"+myVideoName);
//Set the video URI
myVideo.setVideoURI(myVideoUri);
//Play the video
myVideo.start();
https://gist.github.com/jrejaud/b5eb1b013c27a1f3ae5f
I think that you need to look at this -- it should have everything you want.
EDIT: If you don't want to look at the link -- this pretty much sums up what you'd like.
MediaPlayer mp = MediaPlayer.create(context, R.raw.sound_file_1);
mp.start();
But I still recommend reading the information at the link.
It sounds maybe like you have the same issue as i do. instead of using MP4, is 3GPP possible? i think i used like HandBrake or something as the video converter... you just need to make sure you have the right encoder, like H.264x or something. sorry for being a little vague, it's been a while. Also, if it's possible, don't bother worrying about android 2.1 anymore, and also, something things just WILL NOT WORK IN EMULATOR. so if it works on a lot of devices, then just assume it works (especially with different manufacurers)
here, you can read my problem and how i solved the issue (after a long time and no one had an answer). i explained in a lot more detail here:
android media player not working
In the fileName you must put the relative path to the file (without /asset)
for example:
player.setDataSource(
getAssets().openFd(**"media/video.mp4"**).getFileDescriptor()
);
Use the MediaPlayer API and the sample code.
Put the media file in raw folder.
Get the file descriptor to the file.
mediaplayer.setDataSource(fd,offset,length); - its a three
argument constructor.
Then when onPreared , mediaplayer.start();
MainCode
Uri raw_uri=Uri.parse("android.resource://<package_name>/+R.raw.<video_file_name>);
myVideoView=(VideoView)findViewbyID(R.idV.Video_view);
myVideoView.setVideoURI(raw_uri);
myVideoView.setMediaController(new MediaController(this));
myVideoView.start();
myVideoView.requestFocus();
XML
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<VideoView
android:id="+#/Video_View"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
I have prepared a code to just play a simple mp4 file from my res folder. The coding is something like this:
public class VideoPlayer extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video);
VideoView video = (VideoView)findViewById(R.id.VideoView);
Uri uri = Uri.parse("android.resource://company.software.myapp/"
+ R.raw.myvideo);
MediaController mc = new MediaController(this);
video.setMediaController(mc);
video.setVideoURI(uri);
//video.requestFocus();
video.start();
}
}
Now though there is no error in playing. The activity automatically generates a dialog saying "sorry this video cannot be played", but I can hear the audio and it plays till end. What is the problem?
Thanx a lot commonsware.com... but i found the solution to the problem... And astonishingly its the PC processor which is the culprit... I checked n a higher configuration and guess wat... it worked perfectly fine... though sometimes if we do some processing in the background the dialog box does come up but on clicking ok it starts playing the video after some time...
But i confirm that this technique of playing file from resource is ok as far as i know...
sorry to waste ur precious time in a mundane hardware problem... but hope it'll be useful for other people who get this problem...
Android supports 3gp and mp4 format, but still sometimes there are problems in playing an mp4 content.
one thing what I have found out from my research is that, this might be because the resolution problem with the video.
I think that you should re-size the resolution of your mp4 video. This might help.
I have not attempted to play a video clip out of a resource, and I am not certain that it works.
As a test, put the video clip on the SD card and use that as the source of your video.
If you get the same symptoms, then either the MP4 file has issues or it is something with your test environment (e.g., you are using the emulator and don't have a quad-core CPU).
If the SD card test works, though, then I suspect the problem is packaging it as a resource.