android:mediaplayer error(1, -12) - android

When I call getCurrentMillis in android media player it throws IllegalStateException and I see the following in the logs:
E/MediaPlayer: error (1, -12)
I have checked that the video is being correctly prepared.
It also causes OnErrorListener.onError to be called with args 1 and -12.

In the end I found that this was caused by trying to play a video which was only 48px wide. Since I had cropped the video in ffmpeg from a larger one I was able to use a bigger crop. When I increased the width to 64px, the error no longer occurred.
Maybe media player has an undocumented minimum allowed size or maybe the narrower crop was in violation of the H264 spec or something. Hope this helps someone.

Related

MediaPlayer delayed a few seconds before onComplete got called on some devices

I tried to play a local mp4 video file on my TV Box. I found a weird issue with MediaPlayer's playback speed. Here're my logs:
19:30:09.346 E/MediaPlayerManager: currentMediaPlayer's duration = 16021
19:30:09.715 E/MediaPlayerManager: setOnInfoListener - MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START
19:30:27.982 E/MediaPlayerManager: onComplete
The media duration was 16s, but it took about 18s to complete the video's playback. There's always a 2s delay before the onComplete listener got called. Does anyone have a solution for this?
After some experiments, I found out the issue was the large SurfaceView. If I replaced it with a TextureView or create the SurfaceView with smaller size, there's no extra delays.
P/s: I knew ExoPlayer, but for some specific reason, I could not use it.

MediaCodec.createInputSurface() throws IllegalStateException on some devices

I'm working on a video processing app. The app has one Activity that contains a Fragment. The Fragment in turn contains a VideoSurfaceView derived from GLSurfaceView for me to show the preview of the video with effect (using OpenGL) to users. After previewing, users can start processing the video.
To process the video, I mainly apply the method described in here.
Everything works fine on most devices, but the Oppo Mirror 3 (Android 4.4). On this device, everytime I try to create an Surface using MediaCodec.createInputSurface(), it throws out java.lang.IllegalStateException with code -38.
E/OMXMaster: A component of name 'OMX.qcom.audio.decoder.aac' already exists, ignoring this one.
E/SoftAVCEncoder: internalSetParameter: StoreMetadataInBuffersParams.nPortIndex not zero!
E/OMXNodeInstance: OMX_SetParameter() failed for StoreMetaDataInBuffers: 0x80001001
E/ACodec: [OMX.google.h264.encoder] storeMetaDataInBuffers (output) failed w/ err -2147483648
E/OMXNodeInstance: createInputSurface requires COLOR_FormatSurface (AndroidOpaque) color format
E/ACodec: [OMX.google.h264.encoder] onCreateInputSurface returning error -38
E/VideoProcessing: java.lang.IllegalStateException
at android.media.MediaCodec.createInputSurface(Native Method)
at com.ltpquang.android.core.processing.codec.VideoEncoder.<init>(VideoEncoder.java:46)
at com.ltpquang.android.core.VideoProcessing.setupVideo(VideoProcessing.java:200)
at com.ltpquang.android.core.VideoProcessing.<init>(VideoProcessing.java:167)
at com.ltpquang.android.ui.activity.PreviewEditActivity.lambda$btNext$12(PreviewEditActivity.java:723)
at com.ltpquang.android.ui.activity.PreviewEditActivity.access$lambda$12(PreviewEditActivity.java)
at com.ltpquang.android.ui.activity.PreviewEditActivity$$Lambda$13.run(Unknown Source)
at java.lang.Thread.run(Thread.java:841)
Playing around a little bit, I observed that:
BEFORE creating and adding the VideoSurfaceView to the layout, I can create MediaCodec encoder and obtain the input surface successfully. And I can create as many as I want if I release the previous MediaCodec before creating a new one, otherwise I can only obtain one and only one input surface regardless how many MediaCodec I have.
AFTER creating and adding the VideoSurfaceView to the layout, there is no chance that I can get the input surface from the MediaCodec, it thows java.lang.IllegalStateException always.
I've tried removing the VideoSurfaceView from the layout, set it to null, before creating the surface, but no luck for me.
I also tried with suggestions from here, or here, but they didn't help.
From this, it seems that my device can only get the software codec. So that I cant create the input surface.
My question is:
Why was that?
If the device's resources is limited, what can I do (release something for example) to continue the process?
If it is related to the software codec, what should I do? How can I detect and release the resource?
Is this related to GL contexts? If yes, what should I do? Should I manage the contexts my self?

Getting Low Res. output video recording even after specifying Max Video Size

I am trying to record video in background.When i use codecs to record the video, it is giving me lowest output of 176 x 144 even if i specify video size of 1920 x 1080. Below is my code.
mediaRec.setCamera(camera);
mediaRec.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4_SP);
mediaRec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRec.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRec.setVideoSize(1920,1080);
But when i set profile using Camcorder Profile, i am getting High resolution(1080p) Video But it has some jittery frames in starting.So i want to use codecs, but if i use codecs with below code my app throws exception on stopping video Recording.Any idea on where i doing wrong.I have tested this code on Nexus 4 & One plus One.
mediaRec.setCamera(camera);
mediaRec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRec.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRec.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

Android MediaCodec Format/Resolution Change mid-stream

I'm processing a live stream via MediaCodec and have a scenario where the MediaFormat changes mid-stream (ie: resolution of the video being decoded changes). Given I'm attaching the decoder to a Surface to render it as soon as I detect the change in resolution on the incoming stream I recreate the decoder before feeding it the new resolution buffer (providing it with the proper new MediaFormat).
I've been getting some weird errors which don't give me too much info as to what could be wrong, ie when calling MediaCodec.configure with the new format and same Surface:
android.media.MediaCodec$CodecException: Error 0xffffffea
at android.media.MediaCodec.native_configure(Native Method)
at android.media.MediaCodec.configure(MediaCodec.java:577)
Which when fetching the CodecException.getDiagnosticInfo it shows nothing that I can really use to understand the reason for the failure: android.media.MediaCodec.error_neg_22
I've also noted the following on the logs and found some related information and am wondering if there's something I need to do regarding the Surface itself (like detaching it from the old instance of the decoder being giving it to the new one):
07-09 15:00:17.217 E/BufferQueueProducer( 139): [SurfaceView] connect(P): already connected (cur=3 req=3)
07-09 15:00:17.217 E/MediaCodec( 5388): native_window_api_connect returned an error: Invalid argument (-22)
07-09 15:00:17.218 E/MediaCodec( 5388): configure failed with err 0xffffffea, resetting...
Looks like calling stop() and release() as well as reinitializing any references I had to the getInputBuffers() and getOutputBuffers() did the trick. At least I don't get the messages/exceptions anymore. Now I just need to figure out the Surface reference part as it seems the resized stream (when resolution changes) is still being fit in the original surface dimensions instead of adjusting the Surface for the new resolution.
If your encoder supports adaptive playback, then apparently you can alter some codec paramaters on the fly:
https://stackoverflow.com/a/34427724/1048170

Get state of MediaPlayer

In my application I get multiple paths from the user (1 to an image, 1 to an audio track, and 1 to a video) and store them in a database. When another Activity is started to view the files, there isn't a guarantee the files will still be at those paths or even exist at all, since the user chose them and may have deleted/moved them. Therefore, I need to be able to check if the files at those paths are valid.
My original plan was to simply catch any Exceptions thrown when constructing + setting up each object.
Here's what I'm using to view each:
Image - a Drawable
Audio - a MediaPlayer
Video - a VideoView
I would have handled each Exception by showing a dialog to the user
However, no Exceptions are thrown and instead I get different error messages
The VideoView shows its own dialog saying "Sorry, this video cannot be played"
The others go to LogCat:
04-10 23:34:43.174: ERROR/PlayerDriver(30): Command PLAYER_SET_DATA_SOURCE completed with an error or info PVMFErrNotSupported
04-10 23:34:43.174: ERROR/MediaPlayer(271): error (1, -4)
04-10 23:34:43.365: ERROR/MediaPlayer(271): Error (1,-4)
Any thoughts on how to get the state of MediaPlayer and VideoView or some other way to check the paths?
Thanks!
You can set OnErrorListener for VideoView and for MediaPlayer. If an error occurs - your listener will be called. Also, you can check both audio and video using MediaPlayer or using VideoView since it contains MediaPlayer to handle both anyway.
BTW, I think that the listener of VideoView is actually set in the MediaPlayer object within the VideoView

Categories

Resources