parent
56538fec1a
commit
5cdad4b719
Binary file not shown.
Binary file not shown.
@ -1,49 +1,180 @@
|
||||
package com.xypower.mpapp;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.hardware.Camera;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Message;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
/*
|
||||
import com.chillingvan.canvasgl.ICanvasGL;
|
||||
import com.chillingvan.canvasgl.glcanvas.BasicTexture;
|
||||
import com.chillingvan.canvasgl.glview.texture.GLTexture;
|
||||
import com.chillingvan.canvasgl.textureFilter.BasicTextureFilter;
|
||||
import com.chillingvan.canvasgl.textureFilter.HueFilter;
|
||||
import com.chillingvan.canvasgl.textureFilter.TextureFilter;
|
||||
import io.antmedia.rtmp_client.RTMPMuxer;
|
||||
|
||||
import com.xypower.stream.camera.InstantVideoCamera;
|
||||
import com.xypower.stream.encoder.video.H264Encoder;
|
||||
import com.xypower.stream.muxer.RTMPStreamMuxer;
|
||||
import com.xypower.stream.publisher.CameraStreamPublisher;
|
||||
import com.xypower.stream.publisher.StreamPublisher;
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class StreamActivity extends AppCompatActivity {
|
||||
|
||||
private RTMPMuxer mRtmpMuxer;
|
||||
private String mUrl;
|
||||
/*
|
||||
private CameraStreamPublisher streamPublisher;
|
||||
private com.chillingvan.instantvideo.sample.test.camera.CameraPreviewTextureView cameraPreviewTextureView;
|
||||
private InstantVideoCamera instantVideoCamera;
|
||||
private Handler handler;
|
||||
private EditText addrEditText;
|
||||
private HandlerThread handlerThread;
|
||||
private TextureFilter textureFilterLT;
|
||||
private TextureFilter textureFilterRT;
|
||||
private com.chillingvan.instantvideo.sample.test.VideoFrameHandlerHelper videoFrameHandlerHelper;
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
initFrameHandlerHelper();
|
||||
setContentView(R.layout.activity_stream);
|
||||
/*
|
||||
cameraPreviewTextureView = findViewById(R.id.camera_produce_view);
|
||||
cameraPreviewTextureView.setOnDrawListener(new H264Encoder.OnDrawListener() {
|
||||
@Override
|
||||
public void onGLDraw(ICanvasGL canvasGL, List<GLTexture> producedTextures, List<GLTexture> consumedTextures) {
|
||||
|
||||
GLTexture texture = producedTextures.get(0);
|
||||
drawVideoFrame(canvasGL, texture.getSurfaceTexture(), texture.getRawTexture());
|
||||
}
|
||||
|
||||
});
|
||||
addrEditText = (EditText) findViewById(R.id.ip_input_test);
|
||||
|
||||
|
||||
instantVideoCamera = new InstantVideoCamera(Camera.CameraInfo.CAMERA_FACING_FRONT, 640, 480);
|
||||
// instantVideoCamera = new InstantVideoCamera(Camera.CameraInfo.CAMERA_FACING_FRONT, 1280, 720);
|
||||
|
||||
handlerThread = new HandlerThread("StreamPublisherOpen");
|
||||
handlerThread.start();
|
||||
handler = new Handler(handlerThread.getLooper()) {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
super.handleMessage(msg);
|
||||
// StreamPublisher.StreamPublisherParam streamPublisherParam = new StreamPublisher.StreamPublisherParam();
|
||||
// StreamPublisher.StreamPublisherParam streamPublisherParam = new StreamPublisher.StreamPublisherParam(1080, 640, 9500 * 1000, 30, 1, 44100, 19200);
|
||||
StreamPublisher.StreamPublisherParam streamPublisherParam = new StreamPublisher.StreamPublisherParam.Builder().setWidth(540).setHeight(750).setVideoBitRate(1500 * 1000).setFrameRate(30).setIframeInterval(1).setSamplingRate(44100).setAudioBitRate(32000).createStreamPublisherParam();
|
||||
streamPublisherParam.outputFilePath = getExternalFilesDir(null) + "/test_flv_encode.flv";
|
||||
// streamPublisherParam.outputFilePath = getExternalFilesDir(null) + "/test_mp4_encode.mp4";
|
||||
streamPublisher.prepareEncoder(streamPublisherParam, new H264Encoder.OnDrawListener() {
|
||||
|
||||
@Override
|
||||
public void onGLDraw(ICanvasGL canvasGL, List<GLTexture> producedTextures, List<GLTexture> consumedTextures) {
|
||||
GLTexture texture = consumedTextures.get(0);
|
||||
drawVideoFrame(canvasGL, texture.getSurfaceTexture(), texture.getRawTexture());
|
||||
}
|
||||
});
|
||||
try {
|
||||
streamPublisherParam.outputUrl = addrEditText.getText().toString();
|
||||
streamPublisher.startPublish();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
((TextView)findViewById(R.id.test_camera_button)).setText("START");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
streamPublisher = new CameraStreamPublisher(new RTMPStreamMuxer(), cameraPreviewTextureView, instantVideoCamera);
|
||||
// streamPublisher = new CameraStreamPublisher(new MP4Muxer(), cameraPreviewTextureView, instantVideoCamera);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
Intent intent = getIntent();
|
||||
if (intent != null) {
|
||||
mUrl = intent.getStringExtra("url");
|
||||
private void initFrameHandlerHelper() {
|
||||
/*
|
||||
videoFrameHandlerHelper = new com.chillingvan.instantvideo.sample.test.VideoFrameHandlerHelper(getApplicationContext());
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
private void drawVideoFrame(ICanvasGL canvasGL, @Nullable SurfaceTexture outsideSurfaceTexture, @Nullable BasicTexture outsideTexture) {
|
||||
// Here you can do video process
|
||||
// 此处可以视频处理,例如加水印等等
|
||||
|
||||
if(textureFilterLT == null) {
|
||||
textureFilterLT = new BasicTextureFilter();
|
||||
}
|
||||
if(textureFilterRT == null) {
|
||||
textureFilterRT = new HueFilter(180);
|
||||
}
|
||||
int width = outsideTexture.getWidth();
|
||||
int height = outsideTexture.getHeight();
|
||||
canvasGL.drawSurfaceTexture(outsideTexture, outsideSurfaceTexture, 0, 0, width /2, height /2, textureFilterLT);
|
||||
canvasGL.drawSurfaceTexture(outsideTexture, outsideSurfaceTexture, 0, height/2, width/2, height, textureFilterRT);
|
||||
videoFrameHandlerHelper.initDrawHelper(width/2, height/2);
|
||||
videoFrameHandlerHelper.drawText(canvasGL);
|
||||
|
||||
openRtmpMuxer(mUrl);
|
||||
}
|
||||
|
||||
protected void openRtmpMuxer(String url) {
|
||||
if (mRtmpMuxer != null) {
|
||||
if (mRtmpMuxer.isConnected()) {
|
||||
mRtmpMuxer.close();
|
||||
}
|
||||
} else {
|
||||
mRtmpMuxer = new RTMPMuxer();
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
// streamPublisher.resumeCamera();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
/*
|
||||
streamPublisher.pauseCamera();
|
||||
if (streamPublisher.isStart()) {
|
||||
streamPublisher.closeAll();
|
||||
}
|
||||
((TextView)findViewById(R.id.test_camera_button)).setText("START");
|
||||
|
||||
int result = mRtmpMuxer.open(url,0, 0);
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
//handlerThread.quitSafely();
|
||||
}
|
||||
|
||||
if (mRtmpMuxer != null) {
|
||||
mRtmpMuxer.close();
|
||||
mRtmpMuxer = null;
|
||||
public void clickStartTest(View view) {
|
||||
TextView textView = (TextView) view;
|
||||
/*
|
||||
if (streamPublisher.isStart()) {
|
||||
streamPublisher.closeAll();
|
||||
textView.setText("START");
|
||||
} else {
|
||||
streamPublisher.resumeCamera();
|
||||
handler.sendEmptyMessage(1);
|
||||
textView.setText("STOP");
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,16 @@
|
||||
package com.xypower.stream;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Created by Chilling on 2018/8/25.
|
||||
*/
|
||||
public class ScreenUtil {
|
||||
|
||||
public static float dpToPx(Context context, float dp) {
|
||||
if (context == null) {
|
||||
return -1;
|
||||
}
|
||||
return dp * context.getResources().getDisplayMetrics().density;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package com.xypower.stream;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
|
||||
import com.chillingvan.canvasgl.ICanvasGL;
|
||||
import com.chillingvan.canvasgl.androidCanvas.IAndroidCanvasHelper;
|
||||
|
||||
/**
|
||||
* Created by Chilling on 2022/11/14.
|
||||
*/
|
||||
|
||||
public class VideoFrameHandlerHelper {
|
||||
|
||||
private final Context context;
|
||||
|
||||
public VideoFrameHandlerHelper(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
private IAndroidCanvasHelper drawTextHelper = IAndroidCanvasHelper.Factory.createAndroidCanvasHelper(IAndroidCanvasHelper.MODE.MODE_ASYNC);
|
||||
private Paint textPaint = new Paint();
|
||||
|
||||
{
|
||||
initTextPaint();
|
||||
}
|
||||
|
||||
private void initTextPaint() {
|
||||
textPaint.setColor(Color.WHITE);
|
||||
textPaint.setTextSize(ScreenUtil.dpToPx(context, 15));
|
||||
}
|
||||
|
||||
public void initDrawHelper(int width, int height) {
|
||||
drawTextHelper.init(width, height);
|
||||
}
|
||||
|
||||
public void drawText(ICanvasGL canvasGL) {
|
||||
drawTextHelper.draw(new IAndroidCanvasHelper.CanvasPainter() {
|
||||
@Override
|
||||
public void draw(Canvas androidCanvas, Bitmap drawingBitmap) {
|
||||
androidCanvas.drawText("白色, White", 100, 100, textPaint);
|
||||
}
|
||||
});
|
||||
Bitmap outputBitmap = drawTextHelper.getOutputBitmap();
|
||||
canvasGL.invalidateTextureContent(outputBitmap);
|
||||
canvasGL.drawBitmap(outputBitmap, 0, 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package com.xypower.stream.camera;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.chillingvan.canvasgl.ICanvasGL;
|
||||
import com.chillingvan.canvasgl.glview.texture.GLMultiTexProducerView;
|
||||
import com.chillingvan.canvasgl.glview.texture.GLTexture;
|
||||
import com.chillingvan.canvasgl.glview.texture.gles.EglContextWrapper;
|
||||
import com.xypower.stream.VideoFrameHandlerHelper;
|
||||
import com.xypower.stream.encoder.video.H264Encoder;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Leon on 2017/4/19.
|
||||
*/
|
||||
|
||||
public class CameraPreviewTextureView extends GLMultiTexProducerView {
|
||||
|
||||
private H264Encoder.OnDrawListener onDrawListener;
|
||||
private VideoFrameHandlerHelper videoFrameHandlerHelper = new VideoFrameHandlerHelper(getContext().getApplicationContext());
|
||||
|
||||
public CameraPreviewTextureView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public CameraPreviewTextureView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public CameraPreviewTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getInitialTexCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
||||
super.onSurfaceTextureAvailable(surface, width, height);
|
||||
if (mSharedEglContext == null) {
|
||||
setSharedEglContext(EglContextWrapper.EGL_NO_CONTEXT_WRAPPER);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceChanged(int width, int height) {
|
||||
super.onSurfaceChanged(width, height);
|
||||
videoFrameHandlerHelper.initDrawHelper(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onGLDraw(ICanvasGL canvas, List<GLTexture> producedTextures, List<GLTexture> consumedTextures) {
|
||||
onDrawListener.onGLDraw(canvas, producedTextures, consumedTextures);
|
||||
videoFrameHandlerHelper.drawText(canvas);
|
||||
}
|
||||
|
||||
public void setOnDrawListener(H264Encoder.OnDrawListener l) {
|
||||
onDrawListener = l;
|
||||
}
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
package com.xypower.stream.publisher;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.view.Surface;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.chillingvan.canvasgl.util.Loggers;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by Chilling on 2018/4/14.
|
||||
*/
|
||||
public class MediaPlayerHelper {
|
||||
|
||||
public static final String TEST_VIDEO_MP4 = "test_video.mp4";
|
||||
private MediaPlayer mediaPlayer;
|
||||
private String videoName;
|
||||
|
||||
public MediaPlayerHelper() {
|
||||
this(TEST_VIDEO_MP4);
|
||||
}
|
||||
|
||||
public MediaPlayerHelper(String videoName) {
|
||||
this.videoName = videoName;
|
||||
}
|
||||
|
||||
public boolean isPlaying() {
|
||||
if (mediaPlayer != null) {
|
||||
return mediaPlayer.isPlaying();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isLooping() {
|
||||
if (mediaPlayer != null) {
|
||||
return mediaPlayer.isLooping();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void restart() {
|
||||
if (mediaPlayer != null) {
|
||||
mediaPlayer.start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void playMedia(final Context context, Surface mediaSurface) {
|
||||
mediaPlayer = new MediaPlayer();
|
||||
// mediaPlayer.setVolume(0, 0);
|
||||
try {
|
||||
AssetFileDescriptor afd = context.getAssets().openFd(videoName);
|
||||
mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
|
||||
afd.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||
mediaPlayer.setSurface(mediaSurface);
|
||||
mediaPlayer.setLooping(true);
|
||||
|
||||
mediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
|
||||
@Override
|
||||
public void onSeekComplete(MediaPlayer mediaPlayer) {
|
||||
Loggers.i("onSeekComplete","onSeekComplete----"+mediaPlayer.getCurrentPosition());
|
||||
}
|
||||
});
|
||||
|
||||
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
|
||||
@Override
|
||||
public void onPrepared(MediaPlayer mediaPlayer) {
|
||||
Toast.makeText(context, "onPrepare --> Start", Toast.LENGTH_SHORT).show();
|
||||
mediaPlayer.start();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
|
||||
@Override
|
||||
public void onCompletion(MediaPlayer m) {
|
||||
Toast.makeText(context, "End Play", Toast.LENGTH_LONG).show();
|
||||
m.stop();
|
||||
m.release();
|
||||
mediaPlayer = null;
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
mediaPlayer.prepare();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void pause() {
|
||||
if (mediaPlayer != null) {
|
||||
mediaPlayer.pause();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void release() {
|
||||
if (mediaPlayer != null) {
|
||||
mediaPlayer.release();
|
||||
mediaPlayer = null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
*
|
||||
* *
|
||||
* * * Copyright (C) 2017 ChillingVan
|
||||
* * *
|
||||
* * * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* * * you may not use this file except in compliance with the License.
|
||||
* * * You may obtain a copy of the License at
|
||||
* * *
|
||||
* * * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* * *
|
||||
* * * Unless required by applicable law or agreed to in writing, software
|
||||
* * * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * * See the License for the specific language governing permissions and
|
||||
* * * limitations under the License.
|
||||
* *
|
||||
*
|
||||
*/
|
||||
|
||||
package com.xypower.stream.publisher;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.opengl.GLES20;
|
||||
import androidx.annotation.Nullable;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.chillingvan.canvasgl.ICanvasGL;
|
||||
import com.chillingvan.canvasgl.glcanvas.BasicTexture;
|
||||
import com.chillingvan.canvasgl.glcanvas.RawTexture;
|
||||
import com.chillingvan.canvasgl.glview.texture.GLSurfaceTextureProducerView;
|
||||
import com.chillingvan.canvasgl.textureFilter.BasicTextureFilter;
|
||||
import com.chillingvan.canvasgl.textureFilter.TextureFilter;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Chilling on 2016/11/3.
|
||||
*/
|
||||
|
||||
public class ProduceTextureView extends GLSurfaceTextureProducerView {
|
||||
|
||||
private TextureFilter textureFilter = new BasicTextureFilter();
|
||||
// private Bitmap bitmap;
|
||||
|
||||
public ProduceTextureView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public ProduceTextureView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public ProduceTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onSurfaceCreated() {
|
||||
// bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.lenna);
|
||||
setProducedTextureTarget(GLES20.GL_TEXTURE_2D);
|
||||
super.onSurfaceCreated();
|
||||
}
|
||||
|
||||
public void setTextureFilter(TextureFilter textureFilter) {
|
||||
this.textureFilter = textureFilter;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onGLDraw(ICanvasGL canvas, SurfaceTexture producedSurfaceTexture, RawTexture producedRawTexture, @Nullable SurfaceTexture sharedSurfaceTexture, @Nullable BasicTexture sharedTexture) {
|
||||
if (TestVideoEncoder.drawCnt == 19 || TestVideoEncoder.drawCnt == 39) {
|
||||
// canvas.drawBitmap(bitmap, 0, 0);
|
||||
}
|
||||
TestVideoEncoder.drawRect(canvas, TestVideoEncoder.drawCnt);
|
||||
}
|
||||
}
|
@ -0,0 +1,152 @@
|
||||
/*
|
||||
*
|
||||
* *
|
||||
* * * Copyright (C) 2017 ChillingVan
|
||||
* * *
|
||||
* * * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* * * you may not use this file except in compliance with the License.
|
||||
* * * You may obtain a copy of the License at
|
||||
* * *
|
||||
* * * http://www.apache.org/licenses/LICENSE-2.0
|
||||
* * *
|
||||
* * * Unless required by applicable law or agreed to in writing, software
|
||||
* * * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* * * See the License for the specific language governing permissions and
|
||||
* * * limitations under the License.
|
||||
* *
|
||||
*
|
||||
*/
|
||||
|
||||
package com.xypower.stream.publisher;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.media.MediaCodec;
|
||||
import android.util.Log;
|
||||
|
||||
import com.chillingvan.canvasgl.ICanvasGL;
|
||||
import com.chillingvan.canvasgl.glcanvas.GLPaint;
|
||||
import com.chillingvan.canvasgl.glcanvas.RawTexture;
|
||||
import com.chillingvan.canvasgl.glview.texture.GLTexture;
|
||||
import com.chillingvan.canvasgl.glview.texture.gles.EglContextWrapper;
|
||||
import com.chillingvan.canvasgl.util.Loggers;
|
||||
import com.xypower.stream.encoder.MediaCodecInputStream;
|
||||
import com.xypower.stream.encoder.video.H264Encoder;
|
||||
import com.xypower.stream.publisher.StreamPublisher;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Chilling on 2016/12/10.
|
||||
*/
|
||||
|
||||
public class TestVideoEncoder {
|
||||
|
||||
private H264Encoder h264Encoder;
|
||||
private byte[] writeBuffer = new byte[1024 * 64];
|
||||
private Context ctx;
|
||||
private EglContextWrapper eglCtx;
|
||||
public static int drawCnt;
|
||||
private OutputStream os;
|
||||
private List<GLTexture> glTextureList = new ArrayList<>();
|
||||
|
||||
public TestVideoEncoder(Context ctx, final EglContextWrapper eglCtx) {
|
||||
this.ctx = ctx;
|
||||
this.eglCtx = eglCtx;
|
||||
|
||||
try {
|
||||
os = new FileOutputStream(ctx.getExternalFilesDir(null) + File.separator + "test_h264_encode.h264");
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void prepareEncoder(H264Encoder.OnDrawListener onDrawListener) {
|
||||
try {
|
||||
h264Encoder = new H264Encoder(new StreamPublisher.StreamPublisherParam.Builder().createStreamPublisherParam(), eglCtx);
|
||||
for (GLTexture texture : glTextureList) {
|
||||
h264Encoder.addSharedTexture(texture);
|
||||
}
|
||||
h264Encoder.setOnDrawListener(onDrawListener);
|
||||
} catch (IOException | IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void addSharedTexture(RawTexture outsideTexture, SurfaceTexture outsideSurfaceTexture) {
|
||||
glTextureList.add(new GLTexture(outsideTexture, outsideSurfaceTexture));
|
||||
}
|
||||
|
||||
public static void drawRect(ICanvasGL canvasGL, int drawCnt) {
|
||||
GLPaint glPaint = new GLPaint();
|
||||
glPaint.setColor(Color.BLUE);
|
||||
canvasGL.drawRect(new Rect(10 * drawCnt - 20, 50, 10 * drawCnt, 100), glPaint);
|
||||
}
|
||||
|
||||
|
||||
public void start() {
|
||||
Log.d("TestVideoEncoder", "start: ");
|
||||
h264Encoder.start();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (h264Encoder == null) {
|
||||
return;
|
||||
}
|
||||
h264Encoder.close();
|
||||
}
|
||||
|
||||
public boolean isStart() {
|
||||
return h264Encoder != null && h264Encoder.isStart();
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (h264Encoder == null) {
|
||||
return;
|
||||
}
|
||||
h264Encoder.close();
|
||||
}
|
||||
|
||||
public boolean encodeAFrame() {
|
||||
if (isStart()) {
|
||||
Loggers.d("TestVideoEncoder", "writeAFrame");
|
||||
h264Encoder.requestRenderAndWait();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void write() {
|
||||
MediaCodecInputStream mediaCodecInputStream = h264Encoder.getMediaCodecInputStream();
|
||||
MediaCodecInputStream.readAll(mediaCodecInputStream, writeBuffer, new MediaCodecInputStream.OnReadAllCallback() {
|
||||
@Override
|
||||
public void onReadOnce(byte[] buffer, int readSize, MediaCodec.BufferInfo bufferInfo) {
|
||||
Loggers.d("TestVideoEncoder", String.format("onReadOnce: readSize:%d", readSize));
|
||||
if (readSize <= 0) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
os.write(buffer, 0, readSize);
|
||||
os.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue