I am developing an Android application which should record a video. There are certain classes that I cannot change due to restrictions of the project, like Preview and VideoRec classes.
Application has one main screen activity and there is a toggle button. Whenever toggle button is checked, video recording should start and vice versa for the unchecked state.
However, VideoRec class' constructor takes a View type parameter for input (VideoRec(View x)). Main activity's screen has a surfaceview and several buttons. What I am trying to do is to just initiate video recording on the same screen, just like the default mediarecorder application of any phone.
My question is; I keep on failing to obtain the View of the screen. I can't use preview or surfaceView types, I get errors saying either classCast Exceptions or invalid preview/surface preview.
Long story short, how can i get the activity's screen as a type of View?
you can provide a public method in your Main Activity which returns the view you need.
Obviously you have to save a reference of that view in your onCreate method activity:
View myView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.the_layout_id);
myView = (View)findViewByID(R.id.your_id_view);
}
public View getTheView(){
return myView;
}
What I understand is you have 1 surfaceview where reproducing what you are recording.
So you must attach your PreviewCallback in the surfaceChanged(...) SurfaceHolder.Callback! After doing this, you'll continue to get preview frame data after a MediaRecorder is running!
For example:
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
mCamera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] _data, Camera _camera) {
Log.d("onPreviewFrame-surfaceChanged",String.format("Got %d bytes of camera data", _data.length));
}
});
}
Hope it helps!Cheers
Related
I am having an issue with while switching GLSurfaceView. I have a GLSurfaceView (connected with Camera) and I want to move it to another view , but when I am moving it it's losing its frames and showing blackScreen after switching. and when I am reconnecting it to Camera, it starts show my Camera but with delay.
Could any one please tell me solution to move it to another parent without losing its frames (because when I am reconnecting it its showing frames with 2-3 seconds delay).
Please find code written below :
(Here VideoPanel (extends GLSurfaceView) is Frame provided by oovooSDK to show video)
final VideoPanel movingVideoView = parent1.getChildAt(0);
movingView.onPause();
parent1.removeView(movingView);
parent2.addView(movingView);
movingView.onResume();
movingView.requestRender();
for reconnecting :
application.unbindVideoPanel(videoView.userId, videoView.videoRender);
application.unbindVideoPanel(videoView.userId, videoView.videoRender);
// this methods shows delay of 2-3 seconds for binding view again
I tried following methods also
((VideoPanel) videoView.videoRender).setPreserveEGLContextOnPause(true);
// to save context when paused
((VideoPanel)videoView.videoRender).setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); // to render frame again when requestRender is called
Camera is not proper release when your activity going to end.
If you are using a Surface view than release your camera in onSurfaceDestroy
public void surfaceDestroyed(SurfaceHolder holder) {
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}
Also recommend a release your camera if it's not ever going to use.
protected void onDestroy(){
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
}
I am using the camera flash for a Morse code application. I create a new camera object when the class is created. The user has a button which is used to reset and also release the camera when required (If they want to stop the light Morse sequence prematurely).
The problem is that when they hit the reset button because the activity is not created or loaded again the camera never get reinitialized - this is a problem because the method of the class that it is calling is used by another class and releases the camera when it is has completed it's function. I am not sure how to structure the code in a way that allows me to do this.
I am wondering if anyone has any advice/suggestions in how to achieve this?
//Camera object being declared
Light light;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity__morse);
//Camera object being initialized
light = new Light
}
//Reset user pressed a button
public void reset(View view)
{
light.release();
}
//Releasing the camera
public void release() {
if(camera != null)
{
camera.stopPreview();
camera.release();
camera = null;
}
}
Don't initialize the camera in onCreate. Do it in onStart, and release it in onStop.
(Sorry for my english)
I 'm trying to show video using TextureView, but I need to know if there is a way to hide the video without stopping audio playback.
Thus I am doing:
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
mySurface = new Surface(surface);
if(MyService.mMediaPlayer != null) MyService.mMediaPlayer.setSurface(mySurface);
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
if(MyService.mMediaPlayer != null) MyService.mMediaPlayer.setSurface(null);
return false;
}
You can see that I'm trying using setSurface(null) but the audio does not remain when I try this.
EDIT:
I have a button in my main activity ( "show video") ; this button starts the second activity where I put the above code .
I need the audio keeps playing when I press the Back button or the home button
Set the visibility of your TextureView to INVISIBLE
mTextureView.setVisibility(View.INVISIBLE);
I have a 3D cube and I open the camera preview, and I want to see this rotating cube displayed over the camera.
What I attempted is, inside the SurfaceChanged method of the class that implements surfaceHolder.callback, I call camera.setPreviewCallback(new PreviewCallback(){ }
as follows:
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
.......
.......
.......
camera.setPreviewCallback(new PreviewCallback() {
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
// TODO Auto-generated method stub
glSurface.setRenderer( new MyRender());
setContentView(glSurface);
}
});
This code results in, displaying the camera preview for a few seconds until the surface is changed, then, the camera preview disappears and the 3D cube appears on a black background.
Is there anyway to show both surfaces?
As far as I recall, you have to set the CameraPreview ontop of the GlView. Thats not intuitive, but should work.
here is a link that may help you: http://digitalbreed.com/2009/android-render-opengl-on-top-of-camera-preview
You can do your own offscreen compositing, then draw the result into a single SurfaceView. See this sample code for details.
I have an AsyncTask, where I hide a video view, start the video playback, and show the video view when the video is playing.
But the video would just not start when the video view is set to invisible, the async task keeps hanging in onBackground. If I comment out this line, the video starts playing.
Why does the video view require a visible surface?
public void walk(final View v) {
new AsyncTask() {
#Override
protected void onPreExecute() {
super.onPreExecute();
mVideoView.setVisibility(View.INVISIBLE); // this line causes video not to start
mVideoView.start();
}
#Override
protected Object doInBackground(Object... objects) {
while (!mVideoView.isPlaying()) {}
return null;
}
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
mVideoView.setVisibility(View.VISIBLE);
}
}.execute();
A bit of background why I'm doing this: I try to avoid the well-known issue of the black flash that you usually have when starting a video:
https://stackoverflow.com/search?q=%5Bandroid%5D+videoview+black
https://stackoverflow.com/search?q=%5Bandroid%5D+video+%5Bmediaplayer%5D+black
The VideoView is really a specialised SurfaceView. A SurfaceView works by creating another window behind the normal window (containing all of the views), and then having an area of transparency so that the new window (with its own drawing surface) can be seen behind it.
If a SurfaceView is no longer visible, its surface will be destroyed i.e. SurfaceHolder.Callback.surfaceDestroyed is called. The VideoView will not try to play its video if there is not a valid surface, hence your AsyncTask will be able to never leave doInBackground.
The Surface will be created for you while the SurfaceView's window is visible; you should implement surfaceCreated(SurfaceHolder) and surfaceDestroyed(SurfaceHolder) to discover when the Surface is created and destroyed as the window is shown and hidden.