I want to play a video from Firebase storage with a videoview I'm trying like this:
storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
//Toast.makeText(Chat.this, uri.toString(), Toast.LENGTH_SHORT).show();
MediaController mc = new MediaController(Chat.this);
videoView.setMediaController(mc);
videoView.setVideoURI(uri);
videoView.requestFocus();
//videoView.start();
}
});
But it wont play. The video is empty.
First of all, be certain that the video in Storage is actually in a format that Android devices can play. VideoView cannot play everything - only the types of videos that Android supports.
What you're doing now by passing the uri directly into the VideoView is interpreted as an attempt to stream the video from the given uri. Firebase Storage doesn't support video streaming, so that's won't work. Streaming from a uri requires that the server on the other end be able to stream the given resource.
If want to play a video from Storage, you'll have to download entirety first, saved to a local file, then point the VideoView at the local file for playback.
I think the time is late for the answer, but this answer to those who are looking for it later:
Via RecyclerView View dial Uri from the data Snapshot in adapter
#Override
protected void onStart() {
super.onStart();
final FirebaseRecyclerAdap...///
) {
#Override
protected void popul...////
/////
viewHolder.setVideo(Uri.parse(String.valueOf(videoUri)),model.getVideo());
// Here the position is sent to videoview adapter
final String post_key = getRef( position ).getKey().toString();
final String post_id = String.valueOf(post_key);
viewHolder.setUid(model.getUid());
// Here the position is sent to videoview adapter
viewHolder.setVideo(post_id);
viewHolder.setUserprofile(getApplication(),model.getUserprofile());
}
yourAdpater ....
}
public static class ViewHolder extends RecyclerView.ViewHolder {
View mView;
Videoview post_video ;
public ViewHolder(View itemView) {
super(itemView);
mView = itemView;
post_video = (VideoView ) mView.findViewById(R.id.videoView);
}
public void setVideo(final String post_id) {
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//
Uri uri=Uri.parse(dataSnapshot.child(post_id).child("video").getValue(true).toString());
//You can set up the video display as you like
post_video.setVideoURI(uri);
post_video.requestFocus();
post_video.start();
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
The databases should look like this:
look here.
good luck.
may be possible this by storing videos URLs in Database, then present them in Recyclerview which consists of Webview/Youtube Integration in Single row
I had the same problem and the following solution worked for me:
Add this string to AndroidManifest.xml file
<uses-permission android:name="android.permission.INTERNET" />
Related
I am making an app using Java in android studio, and in it I want users to have the option to set a custom profile picture. I'm using firebase storage to store the images for the PFPs, and taking them from there every time I load it, but it always takes around half a second or so to load the profile picture: gif of the problem
Here's my code for loading the pfp in the homepage (I am using de.hdodenhof.circleimageview.CircleImageView to make the ImageView circular):
public class HomePage extends AppCompatActivity {
de.hdodenhof.circleimageview.CircleImageView pfpImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_page);
pfpImage = findViewById(R.id.pfpImg);
Intent intent = getIntent();
if (intent != null && intent.hasExtra("UserEmail")) {
String userEmail = intent.getExtras().getString("UserEmail");
StorageReference userPfp = DBRef.refStorage.child("ProfileImages/Users/" + userEmail.replace(".",",")); //DBRef is a class I created to reference all Firebase related objects.
userPfp.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Picasso.with(HomePage.this).load(uri).into(pfpImage); // I am using com.squareup.picasso:picasso:2.5.2 to load the image from the Uri.
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(HomePage.this, "Profile Picture Loading Failed", Toast.LENGTH_SHORT).show();
}
});
}
else
pfpImage.setImageResource(R.drawable.doggo);
}
}
Is there some better way to load/store the pictures so they appear when the page loads?
EDIT: I managed to negate this by not loading from Firebase every time the activity is opened, but only the first time and saving it, using an idea from this post
There is other library named glide that can load picture faster when the page loads.
Here is the link for the reference.
https://guides.codepath.com/android/Displaying-Images-with-the-Glide-Library
I have an application that downloads JSON input from a web site that returns a URI to a picture or a video. I had no problem to get my MaterialCardView to display the pictures via an ImageView. My plan was to set an overlay VideoView that would be visible only when the specific item was a video type. Here is the XML of the 2 views:
<ImageView
android:id="#+id/picture_image"
android:layout_width="377dp"
android:layout_height="429dp"
android:layout_marginBottom="84dp"
android:adjustViewBounds="true"
android:contentDescription="#string/nasa_pictures_list_id"
android:padding="2dp"
android:scaleType="centerCrop"
app:imageUrl="#{picture.imgSrcUrl}"
app:layout_constraintBottom_toTopOf="#+id/picture_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.47"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_conversion_absoluteHeight="191dp"
tools:layout_conversion_absoluteWidth="411dp"
tools:src="#tools:sample/backgrounds/scenic" />
<!-- android:visibility="#{picture.image ? View.VISIBLE : View.GONE}"-->
<VideoView
android:id="#+id/picture_video"
android:layout_width="377dp"
android:layout_height="429dp"
android:layout_marginBottom="84dp"
android:adjustViewBounds="true"
android:contentDescription="#string/nasa_pictures_list_id"
android:padding="2dp"
android:scaleType="centerCrop"
app:imageUrl="#{picture.imgSrcUrl}"
app:layout_constraintBottom_toTopOf="#+id/picture_title"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.47"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_conversion_absoluteHeight="191dp"
tools:layout_conversion_absoluteWidth="411dp"
tools:src="#tools:sample/backgrounds/scenic" />
<!-- android:visibility="#{picture.video ? View.VISIBLE : View.GONE}"-->
I commented out the android:visibility code for now.
My problem is that the VideoView has a compile error on the app:imageUrl="#{picture.imgSrcUrl}" that works just fine on the preceding ImageView. The error is:
Cannot find a setter for <android.widget.VideoView app:imageUrl> that accepts parameter type 'java.lang.String'
OK I get it, it does not like String.
My question is what does it like and
how do you specify it in a XML layout file?
Thanks page
I have come to the conclusion that you can not do this via the XML file. I can not find a single example where this is being done. What I did do was adapt code that I found in the SampleVideoView in the Advanced Android Training that worked and can be found here; https://github.com/google-developer-training/android-advanced/tree/master/SimpleVideoView
First I created a Java class in in my app like this:
public class VideoViewAdapter {
private String VIDEO_SAMPLE =
"https://images.all-free-download.com/footage_preview/mp4/rocket_launch_cape_caneveral_nasa_535.mp4";
private Context mContext;
private VideoView mVideoView;
// Current playback position (in milliseconds).
private int mCurrentPosition = 0;
// Tag for the instance state bundle.
private static final String PLAYBACK_TIME = "play_time";
public void initVideo(Context context, VideoView videoView) {
// Set up the media controller widget and attach it to the video view.
mVideoView = videoView;
MediaController controller = new MediaController(context);
controller.setMediaPlayer(mVideoView);
mVideoView.setMediaController(controller);
mContext = context;
}
public void initializePlayer(VideoView videoView,String url, int position) {
if(url!=null) VIDEO_SAMPLE = url;
if(position!=0) mCurrentPosition = position;
mVideoView = videoView;
// Buffer and decode the video sample.
Uri videoUri = getMedia(VIDEO_SAMPLE);
mVideoView.setVideoURI(videoUri);
// Listener for onPrepared() event (runs after the media is prepared).
mVideoView.setOnPreparedListener(
new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
// Restore saved position, if available.
if (mCurrentPosition > 0) {
mVideoView.seekTo(mCurrentPosition);
} else {
// Skipping to 1 shows the first frame of the video.
mVideoView.seekTo(1);
}
// Start playing!
mVideoView.start();
}
});
// Listener for onCompletion() event (runs after media has finished
// playing).
mVideoView.setOnCompletionListener(
new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
Toast.makeText(mContext,
R.string.toast_message,
Toast.LENGTH_SHORT).show();
// Return the video position to the start.
mVideoView.seekTo(0);
}
});
}
// Release all media-related resources. In a more complicated app this
// might involve unregistering listeners or releasing audio focus.
public void releasePlayer() {
mVideoView.stopPlayback();
}
// Get a Uri for the media sample regardless of whether that sample is
// embedded in the app resources or available on the internet.
private Uri getMedia(String mediaName) {
if (URLUtil.isValidUrl(mediaName)) {
// Media name is an external URL.
return Uri.parse(mediaName);
} else {
// Media name is a raw resource embedded in the app.
return Uri.parse("android.resource://" + mContext.getPackageName() +
"/raw/" + mediaName);
}
}
}
This provided me with a view adapter that I could instantiate at the top of my MainActivity like this:
in Kotlin now:
.
.
.
lateinit var VIDEOADAPTOR: VideoViewAdapter
.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
.
.
.
VIDEOADAPTOR = VideoViewAdapter()
Then in the Fragment class file for the layout fragment. I placed the following code in the RecyclerView.Adapter class under the onBindViewHolder override.
class DailyPictureAdapter(val callback: PictureClick) : RecyclerView.Adapter<DailyPictureViewHolder>() {
.
.
.
/**
* Called by RecyclerView to display the data at the specified position. This method should
* update the contents of the {#link ViewHolder#itemView} to reflect the item at the given
* position.
*/
override fun onBindViewHolder(holder: DailyPictureViewHolder, position: Int) {
holder.viewDataBinding.also {
it.picture = pictures[position]
it.pictureCallback = callback
if(pictures[position].isVideo) {
VIDEOADAPTOR.initVideo(context, it.pictureVideo)
VIDEOADAPTOR.initializePlayer(it.pictureVideo,it.pictureVideo.pictures[position].imgSrcUrl, 0)
}
}
holder.itemView.setOnClickListener{ callback.onClick(pictures[position])}
}
}
This worked it played the video in the Video View as part of the Recycler View. Nice but....
My issue with this would be memory use. For my app that has 15 to 25 records at a time with only a few of them being Videos this did not present an issue. However if this was a list of Videos I think we would find a memory issue very quickly.
I could not find a good place to release the resources as they scrolled out of view. If someone can comment on that please do.
I'm trying to get audios from firebase storage and play with MediaPlayer. And actually I can do this but the problem is I can't play some of the audios. I realized that it can't play audios which have size higher than 50 kb. I can play audios which the size less than 50 kb.
Btw this is my first question here. Sorry for mistakes.
Errors:
E/FLACExtractor: unsupported sample rate 44000
E/GenericSource: initFromDataSource, source has no track!
E/GenericSource: Failed to init from data source!
E/MediaPlayerNative: error (1, -2147483648)
E/MediaPlayer: Error (1,-2147483648)
public class KelimeSecimActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener {
MediaPlayer mMediaplayer = new MediaPlayer();
private Button buttonBasla ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_kelime_secim);
buttonBasla = findViewById(R.id.buttonBasla);
mMediaplayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
fetchAudioUrlFromFirebase();
buttonBasla.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onPrepared(mMediaplayer);
}
});
}
private void fetchAudioUrlFromFirebase() {
final FirebaseStorage storage = FirebaseStorage.getInstance();
// Create a storage reference from our app
StorageReference storageRef = storage.getReferenceFromUrl("MY_URL");
storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
try {
// Download url of file
final String url = uri.toString();
mMediaplayer.setDataSource(url);
// wait for media player to get prepare
mMediaplayer.setOnPreparedListener(null);
mMediaplayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(),"Failed",Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
As i said, there is no problem if the audio size low than 50 kb. Actually i'm not sure whether it's because of size. But I tried many files and result is like this.
I am able to reproduce the issue. The files you mentioned do work in other players, but don't work in Android's MediaPlayer.
The problem files are all encoded at 44000Hz, using libFLAC 1.1.3.
The files that work are all 44100Hz, using libFLAC 1.1.2.
The size correlation appears to be a coincidence. For instance, En-us-you_re2.flac plays fine. It's 166KB, but it's 44100Hz.
It's clear that 44000Hz is a valid rate, but MediaPlayer simply doesn't support it. You may have better luck with exoplayer with the FLAC extension. Worst case, you might have to find your own decompression library and do the conversion yourself.
I am beginner in android and developing an app in which i am using YouTubePlayer API in order to show Youtube Videos of specific Playlist. I'm succeed in doing so. But what I want is that whenever the user selects any video from that playlist; the video should be played in Full Screen. Here is my code:
public class Main4Activity extends AppCompatActivity
{
Toolbar main_toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
main_toolbar=(Toolbar) findViewById(R.id.my_thirdtoolbar);
setSupportActionBar(main_toolbar);
getSupportActionBar().setTitle(R.string.my_tb_title);
getSupportActionBar().setIcon(R.drawable.tblogo);
OnClickButtonListener();
}
public void OnClickButtonListener()
{
Button youtubebtn = (Button) findViewById(R.id.button8);
youtubebtn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
String PLAYLIST_ID = "PLXRActLQ03oY_6AQb-5EMuKFYQA_fDE40";
Intent intent=YouTubeIntents.createOpenPlaylistIntent(Main4Activity.this,PLAYLIST_ID);
startActivity(intent);
}
}
);
}
}
You can use methods from YouTubeIntents. Here are some methods that you can use:
canResolvePlayVideoIntentWithOptions (Context context)
Checks if the YouTube application installed on the user's device supports the fullscreen and finishOnEnd optional parameters when resolving a play video intent.
If this method returns true, then your application can call the createPlayVideoIntentWithOptions(Context context, String videoId, boolean fullscreen, boolean finishOnEnd) method which creates an Intent that, when resolved, will start playing the video specified by videoId, within the YouTube application.
If this method returns false, then your application should call the createPlayVideoIntent(Context context, String videoId) method instead.
Additionally, please also check other implementations and try the suggested solutions in this SO post. Hope it helps!
Few days back I asked question Youtube API v2 not supported So as per youtube they have deprecated and all application and websites using this v2 api wont work at all. As they told to migrate to v3 there are any good example or documents for android. I have youtube url with video id. I just want to play videos using this api
You can use Video ID to play video...
Use YouTubePlayerView for that...
Let me show you a example which will makes everything clear....
below is a class which contains a YouTubePlayerView..
public class Play_youtube_video extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener
{
YouTubePlayerView video_player;
public static String VIDEO_ID = "";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// HIDE THE KEYBOARD
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
// TITLE BAR DISABLES AND FULL SCREEN IMPLEMENTATION
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_play_youtube_video);
try
{
System.out.println("youtube----VIDEO_ID---->" + VIDEO_ID);
video_player = (YouTubePlayerView) findViewById(R.id.youtubeplayerview_full_screen);
video_player.initialize(GlobalConstant.YOUTUBE_APIKEY, Play_youtube_video.this);
}
catch(Exception e)
{
e.printStackTrace();
}
catch(OutOfMemoryError e)
{
e.printStackTrace();
}
}
#Override
public void onInitializationFailure(Provider provider, YouTubeInitializationResult result)
{
GlobalUtills.showToast("Youtube player not found.", Play_youtube_video.this);
}
#Override
public void onInitializationSuccess(Provider provider, YouTubePlayer player, boolean wasRestored)
{
if( !wasRestored )
{
player.loadVideo(Youtube_VIDEO_ID);
// player.setFullscreen(true);
// player.play();
}
}
public void closeYoutube(View v)
{
Play_youtube_video.this.finish();
}
}
I am answering this question because after some frustration it was not on android api related issue but Gdata youtube api i was using was returning wrong results.
Now its fixed.