How to create a custom control with MvvmCross Droid VideoView - android

I have a viewmodel for searching for videos which works great. I have added a play button and upon clicking I want to load a view that renders a VideoView. The search viewmodel contains enough data to generate the video's URL.
What is the best way to render the VideoView?
I've found this example but it appears to be an older version of MvvmCross:
https://gist.github.com/Alphapage/3945799
Should I create custom control like N=18 - Android Custom Controls - N+1 Days of MvvmCross?
http://www.youtube.com/watch?v=s1LhXdCTsn4&feature=youtube_gdata
If I create a custom control how should I pass the video's URL to the VideoView and start it playing?
I'm sure this is easy to do but I can't find a working example.
Thanks in advance

You could create a custom view as Stuart does, but rather than inheriting from View inherit from VideoView.
Then create a property called VideoUri, and when ever it's set call the SetVideoUri and start method on the base object. E.g.
Please note the following code was written in notepad, so may need some tweaking :)
public class BindableVideoView : VideoView
{
private Uri _videoUri = default(Uri);
public Uri VideoUri
{
get{ return _videoUri;}
set{
if(_videoUri!=value)
{
if(base.IsPlaying)
{
base.StopPlayback();
}
}
base.SetVideoURI(value);
base.Start();
}
}
}
You could do things like expose a property for IsPlaying and then your viewmodel could two-way bind to that so your viewmodel would know when you have finished playing the video

Related

How to set custom layout and font in Exoplayer notification?

I'm using PlayerNotificationManager for displaying playback notifications in my application. Everything is working fine but I want to add my application's logo in the notification with custom fonts.
I changed the play & pause buttons on the notification by adding drawables.xml. But can't find a way to change the font.
So, how can I change the default notification layout and characteristics that Exoplayer provides?
Edit:
I have seen this issue on Github which says that we need to extend PlayerNotificationManager in order to use custom layout. But I can't seem to get it working.
Here is my code:
private void setPlayerNotificationManager(Player player) {
playerNotificationManager = new PlayerNotificationManager(context, "123", 1234, mediaDescriptionAdapter);
playerNotificationManager.setUseNavigationActions(false);
playerNotificationManager.setUsePlayPauseActions(true);
playerNotificationManager.setRewindIncrementMs(0);
playerNotificationManager.setFastForwardIncrementMs(0);
//playerNotificationManager.setColor(Color.GREEN);
playerNotificationManager.setColorized(true);
playerNotificationManager.setUseChronometer(false);
playerNotificationManager.setSmallIcon(R.drawable.logo);
playerNotificationManager.setPlayer(player);
}
As said on the repo you need to extends the PlayerNotificationManager to do that you need to create this class and copy everything inside your project, and then add the layout you want to use as described in this link
You need to add your layout in the builder here

WebRTC for Android : VideoRendererGUI take a screenshot in the video call

The demand is that saving a video frame in the video call. I have made a demo that take a screenshot through the GLSurfaceView's method "onDrawFrame". But when I use the webrtc, it have its own renderer "VideoRendererGUI" .And then when I want to override it, I find it can't be overrided. the main part code :
vsv = (GLSurfaceView) findViewById(R.id.glviewchild_call);
vsv.setPreserveEGLContextOnPause(true);
vsv.setKeepScreenOn(true);
VideoRendererGui.setView(vsv, new Runnable() {
#Override
public void run() {
init();
}
});
And If you have another way to take a screenshot, you can also share with me.
Thanks a lot!
If you use a SurfaceViewRenderer to display the stream, you can use the solution in this answer to capture a frame on the call.
Basically, using surfaceViewRenderer.AddFrameListener with a class that implements EGLRenderer.FrameListener
I will assume that the SurfaceViewRenderer of the peer you want to take a screenshot of is called remotePeerSurfaceViewRenderer, also I will asume that the button that you will use to take a screenshot is called btnScreenshot
So all what you need to do is as "Webo80" said in the answer above use the FrameListener, the issue is the FrameListener implementation of the webrtc takes only the first frame available once the Listener is attached to the SurfaceViewRenderer, so my approach to do that is by attaching the webrtc implementation of the FrameListsner at the second I need to take a screenshot and remove it once it is taken:
btnScreenshot.setOnClickListener((view)-> {
remotePeerSurfaceViewRenderer.addFrameListsner(new EglRenderer.FrameListener() {
#Override
public void onFrame(Bitmap bitmap) {
runOnUiThread(() -> {
/*
do what ever you want with the bitmap for example
imgView.setImageBitmap(bitmap);
*/
localVideoView.removeFrameListener(this);
});
}
}, 1);
})
Important note:
1. Please don't forget to runOnUiThread as Iam doing
2. Please don't forget to remove the listener inside the button onClick() method
I have tried this solution and it is working more than fine, if you want to make your custom solution you have to completely implement the interface "EglRenderer.FrameListener"
I am sorry to say due to unavailability of canvas and other facilities in Android It's not possible to capture screenshot programatically using WebRTC. One can dodge this situation by animating the app's UI and capturing the screenshot manually , store it at configured location and exchange it with other party.

Disabling the youtube icon on the YouTubeStandalonePlayer in android?

I just wanted to know how to disable the youtube icon that comes in the YouTubeStandalonePlayer. Is it possible?
I don't want to take the user to youtube on clicking the icon. Is there any way to disable the youtube icon?
The below is the code how I am playing the the video using the YouTubeStandalonePlayer.
String videoId = getVideoId(cardsInfo.getCard_video_url());
Intent intent = YouTubeStandalonePlayer.createVideoIntent(getActivity(), getResources().getString(R.string.android_key), videoId, 0, true, false);
startActivity(intent);
According to the API, you can't.
But, you can try and use the other (not standalone) classes, which might give you better control as suggested in the docs: There are two ways to play videos. The first option is to place a YouTubePlayerFragment or YouTubePlayerView in your View hierarchy and then use the YouTubePlayer to control video playback in the View. **This gives a fine control of the experience**. If they don't let it, you could atleast have better control of the flow/UI-visibility because you are controling the Activity (in contrast of giving the control to the standalone activity)

Android TV PlaybackControlsRow

So building a new app specifically for the Android TV interface (lollipop leanback) and I'm using the PlaybackOverlayFragment that is provided by the framework which has a PlaybackControlsRow with all the usual controls on it.
The problem is, the default behavior is for the user to have to click the "Play" button to start the video and I want it to start automatically. That part is easy and I have it working but then the Play/Pause icons on the provided control are out of sync (showing play when should be pause) because the item was started outside of the events of clicking on that control.
Documentation is sparse on these framework elements and examining the class I can't find any public method that would allow me to put this control in the proper "mode" or tell it to display the play or pause icon myself.
Anyone with experience with these yet that would know how to do this?
In order to change the state of the button, even after adding your Actions to the Adapter, you'll need to notify the changes to the adapter that has your Action.
mPlayPauseAction.nextIndex(); // next index, if it was pause, it'll be play
notifyChanged(mPlayPauseAction);
// where notifyChanged(Action action) is:
private void notifyChanged(Action action) {
ArrayObjectAdapter adapter = mPrimaryActionsAdapter; // reference to your adapter
if (adapter.indexOf(action) >= 0) {
adapter.notifyArrayItemRangeChanged(adapter.indexOf(action), 1);
return;
}
}
Well, I partially answered my own question.
If I know before the PlaybackControlsRow is created that I want to set it to the pause state (actually, playing state but showing pause button) then if I call setIndex(PlaypauseAction.PAUSE) on the PlayPauseAction before adding it to the controlsrow then it works.
It doesn't appear that I can modify it myself after adding it but that may be something else I'm doing wrong.

Moving between "pages" ( CCLayer ) in cocos2dx

I have 2 MyGameScreen objects that extends cocos2d::CCLayer. I am capturing the ccTouchesMove of the first screen so that I can create the moving effect exactly like sliding between pages of iOS application screen.
My class is like so:
class MyGameScreen: public cocos2d::CCLayer {
cocos2d::CCLayer* m_pNextScreen;
}
bool MyGameScreen::init() {
m_pNextScreen = MyOtherScreen::create();
}
void MyGameScreen::ccTouchesMoved(CCSet *touches, CCEvent *event){
// it crashes here... on the setPosition... m_pNextScreen is valid pointer though I am not sure that MyOtherScreen::create() is all I need to do...
m_pNextScreen->setPosition( CCPointMake( (fMoveTo - (2*fScreenHalfWidth)), 0.0f ) );
}
EDIT: adding clear question
It crashed when I try to setPosition on m_pNextScreen...
I have no idea why it crashed as m_pNextScreen is a valid pointer and is properly initialized. Could anybody explain why?
EDIT: adding progress report
I remodelled the whole system and make a class CContainerLayer : public cocos2d::CCLayer that contains both MyGameScreen and MyOtherScreen side by side. However, this looked like not an efficient approach, as when it grows I may need to have more than 2 pages scrollable side by side, I'd prefer to load the next page only when it is needed rather than the entire CContainerLayer that contains all the upcoming pages whether the user will scroll there or not... Do you have any better idea or github open source sample that does this?
Thank you very much for your input!
Use paging enable scrollview.download files from following link and place in your cocos2d/extenision/gui/ after that you have to set property of scrollview to enablepaging true with paging view size.
https://github.com/shauket/paging-scrollview
For Scene Transitions you can do this:
void MyGameScreen::ccTouchesMoved(CCSet *touches, CCEvent *event)
{
CCScene* MyOtherScene = CCTransitionFadeUp::create(0.2f, MyOtherScreen::scene());
CCDirector::sharedDirector()->replaceScene(MyOtherScene);
}

Categories

Resources