saki4510t / AudioVideoRecordingSample

Simultaneous audio and video recording sample using MediaCodec/MediaMuxer
Apache License 2.0
950 stars 291 forks source link

Recording in square shape #8

Open RockyLin opened 7 years ago

RockyLin commented 7 years ago

Is there a way to record a video in square shape using openGL, without distorting the image? Please help! Thank you!

RockyLin commented 7 years ago

Now you're using GLSurfaceView and the output video is always full screen rectangle. Is there a way to get truly square video?

saki4510t commented 7 years ago

Hi, Do you mean you want to save video images with same with and height? it is possible. It is same as render video images on GLSurfaceView with crop-center mode. I don't test yet, but I assume you will initialize encoder with width and height as minimum value of video width and video height and render video images to the (input) Surface of MediaCodec with crop center mode(you wee need to adjust texture matrix). saki

geek-paulwong commented 7 years ago

Oh, wow, it's working for me, thanks!

geek-paulwong commented 7 years ago

I have an extra question, the MP4 file seems not streamable? How can I make it streamable? ;)

saki4510t commented 7 years ago

Hi, in general, usual MP4(except very short one) is not streamable by it's internal structure. If you want to stream, I assume you should use fragmented MP4. Some open source repositories like mp4parse, mp4parser-smooth-streaming will help you.

geek-paulwong commented 7 years ago

Thank you very much! @saki4510t

RockyLin commented 7 years ago

@saki4510t Thank you for this awesome lib, it solves a big problem of mine. After some efforts, now it's finally working on recording squared video, and turned out to be nice. However, sometimes after the camera is turned on, it just restarts automatically, and the resulting video's image is totally black;

Thanks for your time!

The error log is below. PS: class CameraGLViewFront extends GLSurfaceView , I just changed the name of your CameraGLView. public final class CameraGLView extends GLSurfaceView(Your original class)

screen shot 2016-10-19 at 7 10 27 pm

screen shot 2016-10-19 at 7 11 55 pm

screen shot 2016-10-19 at 7 12 25 pm screen shot 2016-10-19 at 7 12 57 pm

saki4510t commented 7 years ago

Hi, Did you see onSurfaceChanged twice on your log? Usually 'GLSurfaceView.Renderer#onSurfaceChanged' is called with (width,height)=(0,0) and then called with actual view size. First one is called while layout is proceeding and should be ignore (as you can see on line 251 of CameraGLView.java). I assume #onSurfaceChanged may be called twice or more with non-zero size on your device. How does your log say?

RockyLin commented 7 years ago

@saki4510t You are right!! "onSurfaceChanged" appears three times in the log(actually it restart three times ). This phenomenon appears randomly, cannot be regained with the same operation.

Recording result mp4: 480 * 480 Device: Nexus5x, 1080 * 1920 Android 6.0.1

Thanks for your time!

camera

saki4510t commented 7 years ago

Hi, I assume there are at least two workaround. First one is;

  1. create two new fields to hold previous width and height, like mPrevWidth and mPrevHeight.
  2. compare width and height with previous values in onSurfaceChanged if both width and height is not zero.
  3. if width or height changed,
    1. if preview is already started, stop preview
    2. start preview (again)

Second one is;

  1. change sendMessage to sendMessageDelayed and add removeMessages before sendMessageDelayed in CameraHandler#startPreview.

    public void startPreview(final int width, final int height) {
           removeMessages(MSG_PREVIEW_START);
           sendMessageDelayed(obtainMessage(MSG_PREVIEW_START, width, height), DELAY_START_PREVIEW);
    }
  2. As I can see you log, DELAY_START_PREVIEW will be 100 - 300 msec.
RockyLin commented 7 years ago

@saki4510t Thanks a lot! I'll give it try!

hexmonad commented 7 years ago

Hi @RockyLin , if the issue is still actual, you can check out my fork of this project with the square mode implementation: https://github.com/hexmonad/AudioVideoRecordingSample/tree/square-video-recorder

RockyLin commented 7 years ago

@hexmonad Thanks a lot!

RockyLin commented 7 years ago

@hexmonad I've tested your branch demo. Unfortunately, the issue is still there. After the camera is turned on, everything seems to be fine at first. Then maybe 20 seconds later(maybe 1 second later...it appears to be pretty random), the camera black out for a second and reappear(I didn't do anything, not even started to record). And below is the log when it blackout and restart(two "onResume" appears in the log each time it restarts) screen shot 2016-11-05 at 5 08 41 pm screen shot 2016-11-05 at 5 21 18 pm

screen shot 2016-11-05 at 5 20 50 pm

hexmonad commented 7 years ago

@RockyLin , hmm, it's very strange. It looks like something goes to the foreground and pauses your app for a short time, and then go away. Do you have any apps on your device that can affect to the app in a such manner? Also, you can enable the DEBUG flag in the CameraFragment to check out the fragment lifecycle.

avinz commented 7 years ago

Hey, I have the same lag sometimes @RockyLin posted. In logs i can see that fragments was paused.

RockyLin commented 7 years ago

@hexmonad

Thank you!

The size you set is 1280 720, What about small screens? e.g. 782 480

CameraFragment.java mCameraView.setVideoSize(1280, 720); CameraGLView.java mCameraHandler.startPreview(1280, 720/width, height/);

hexmonad commented 7 years ago

@RockyLin , To get the list of supported preview sizes for your device, call the method [getSupportedPreviewSizes()](https://developer.android.com/reference/android/hardware/Camera.Parameters.html#getSupportedPreviewSizes()). The method is used in the project in this place. If your screen size is not in the list, you can scale the preview texture to match the screen (see the setScaleMode method in the CameraGLView class).

knowamit commented 4 years ago

Hi, thank for providing this awesome lib. I have done square recording using the lib, but I am facing the issue of final video bitrate problem, please have a look at this following data.

pts      dts      diff  frame  size  total   pts_delta
-1024    -1024    0     1      23    23      
0        0        0     2      423   446     1024
1812     1812     0     3      424   870     1812
2449     2449     0     4      414   1284    637
3341     3341     0     5      405   1689    892
4123     4123     0     6      357   2046    782
5091     5091     0     7      399   2445    968
6890     6890     0     8      384   2829    1799
7793     7793     0     9      366   3195    903
8519     8519     0     10     391   3586    726
9490     9490     0     11     372   3958    971

the pts_delta should be the same for all frames but I am not able to understand why this is happening. I was looking on the internet about this problem so found out this might be the issue of passing wrong pts to the muxer. Please help it's very critical.