Skip to content

Commit 3f78a9a

Browse files
添加镜像功能
1 parent c1cbb54 commit 3f78a9a

File tree

12 files changed

+163
-8
lines changed

12 files changed

+163
-8
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
<application
1818
android:allowBackup="true"
19-
android:icon="@mipmap/ic_launcher"
19+
android:icon="@mipmap/live"
2020
android:label="@string/app_name"
2121
android:supportsRtl="true"
2222
android:theme="@style/AppTheme">

app/src/main/java/com/wangshuo/wslive/wslivedemo/LiveUI.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package com.wangshuo.wslive.wslivedemo;
22

3+
import android.graphics.Bitmap;
34
import android.view.View;
45
import android.widget.Button;
6+
import android.widget.ImageView;
57
import android.widget.Toast;
68

9+
import me.lake.librestreaming.core.listener.RESScreenShotListener;
710
import me.lake.librestreaming.filter.hardvideofilter.BaseHardVideoFilter;
811
import me.lake.librestreaming.ws.StreamLiveCameraView;
912
import me.lake.librestreaming.ws.filter.hardfilter.FishEyeFilterHard;
@@ -20,13 +23,18 @@ public class LiveUI implements View.OnClickListener {
2023
private StreamLiveCameraView liveCameraView;
2124
private String rtmpUrl = "";
2225
boolean isFilter = false;
26+
boolean isMirror = false;
2327

2428
private Button btnStartStreaming;
2529
private Button btnStopStreaming;
2630
private Button btnStartRecord;
2731
private Button btnStopRecord;
2832
private Button btnFliter;
2933
private Button btnSwapCamera;
34+
private Button btnScreenshot;
35+
private Button btnMirror;
36+
37+
private ImageView imageView;
3038

3139
public LiveUI(LiveActivity liveActivity , StreamLiveCameraView liveCameraView , String rtmpUrl) {
3240
this.activity = liveActivity;
@@ -54,6 +62,20 @@ private void init() {
5462

5563
btnSwapCamera = (Button) activity.findViewById(R.id.btn_swapCamera);
5664
btnSwapCamera.setOnClickListener(this);
65+
66+
btnScreenshot = (Button) activity.findViewById(R.id.btn_screenshot);
67+
btnScreenshot.setOnClickListener(this);
68+
69+
btnMirror = (Button) activity.findViewById(R.id.btn_mirror);
70+
btnMirror.setOnClickListener(this);
71+
72+
imageView = (ImageView) activity.findViewById(R.id.iv_image);
73+
imageView.setOnClickListener(new View.OnClickListener() {
74+
@Override
75+
public void onClick(View view) {
76+
imageView.setVisibility(View.GONE);
77+
}
78+
});
5779
}
5880

5981
@Override
@@ -94,6 +116,26 @@ public void onClick(View view) {
94116
case R.id.btn_swapCamera://切换摄像头
95117
liveCameraView.swapCamera();
96118
break;
119+
case R.id.btn_screenshot://截帧
120+
liveCameraView.takeScreenShot(new RESScreenShotListener() {
121+
@Override
122+
public void onScreenShotResult(Bitmap bitmap) {
123+
if(bitmap != null){
124+
imageView.setVisibility(View.VISIBLE);
125+
imageView.setImageBitmap(bitmap);
126+
}
127+
128+
}
129+
});
130+
break;
131+
case R.id.btn_mirror://镜像
132+
if(isMirror){
133+
liveCameraView.setMirror(true,false,false);
134+
}else {
135+
liveCameraView.setMirror(true,true,true);
136+
}
137+
isMirror = !isMirror;
138+
break;
97139
default:
98140
break;
99141
}

app/src/main/res/layout/layout_activity_live_ui.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@
2424
android:layout_width="wrap_content"
2525
android:layout_height="wrap_content"
2626
android:text="滤镜"/>
27+
<Button
28+
android:id="@+id/btn_screenshot"
29+
android:layout_width="wrap_content"
30+
android:layout_height="wrap_content"
31+
android:text="截帧"/>
32+
<Button
33+
android:id="@+id/btn_mirror"
34+
android:layout_width="wrap_content"
35+
android:layout_height="wrap_content"
36+
android:text="镜像"/>
2737

2838
</LinearLayout>
2939

@@ -61,4 +71,12 @@
6171
</LinearLayout>
6272

6373

74+
<ImageView
75+
android:id="@+id/iv_image"
76+
android:layout_width="wrap_content"
77+
android:layout_height="wrap_content"
78+
android:layout_centerInParent="true"
79+
android:visibility="gone"/>
80+
81+
6482
</RelativeLayout>
51.3 KB
Loading
51.3 KB
Loading

libWSLive/src/main/java/me/lake/librestreaming/client/RESClient.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,10 @@ public void setVideoEncoder(final MediaVideoEncoder encoder) {
516516
videoClient.setVideoEncoder(encoder);
517517
}
518518

519+
public void setMirror(boolean isEnableMirror,boolean isEnablePreviewMirror,boolean isEnableStreamMirror) {
520+
videoClient.setMirror(isEnableMirror,isEnablePreviewMirror,isEnableStreamMirror);
521+
}
522+
519523
static {
520524
System.loadLibrary("restreaming");
521525
}

libWSLive/src/main/java/me/lake/librestreaming/client/RESVideoClient.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,4 +457,7 @@ public void setVideoEncoder(final MediaVideoEncoder encoder) {
457457
videoCore.setVideoEncoder(encoder);
458458
}
459459

460+
public void setMirror(boolean isEnableMirror,boolean isEnablePreviewMirror,boolean isEnableStreamMirror) {
461+
videoCore.setMirror(isEnableMirror,isEnablePreviewMirror,isEnableStreamMirror);
462+
}
460463
}

libWSLive/src/main/java/me/lake/librestreaming/core/GLHelper.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,4 +450,50 @@ public static FloatBuffer getCameraTextureVerticesBuffer() {
450450
private static float flip(final float i) {
451451
return (1.0f - i);
452452
}
453+
454+
455+
public static FloatBuffer adjustTextureFlip(boolean flipHorizontal) {
456+
float[] textureCords = getFlip(flipHorizontal, false);
457+
FloatBuffer mTextureBuffer = null;
458+
if (mTextureBuffer == null) {
459+
mTextureBuffer = ByteBuffer.allocateDirect(textureCords.length * 4)
460+
.order(ByteOrder.nativeOrder())
461+
.asFloatBuffer();
462+
}
463+
mTextureBuffer.clear();
464+
mTextureBuffer.put(textureCords).position(0);
465+
466+
return mTextureBuffer;
467+
}
468+
469+
public static float[] getFlip(final boolean flipHorizontal,
470+
final boolean flipVertical) {
471+
float[] rotatedTex = Cam2dTextureVertices;
472+
473+
if (flipHorizontal) {
474+
rotatedTex = new float[]{
475+
flip2(rotatedTex[0]), rotatedTex[1],
476+
flip2(rotatedTex[2]), rotatedTex[3],
477+
flip2(rotatedTex[4]), rotatedTex[5],
478+
flip2(rotatedTex[6]), rotatedTex[7],
479+
};
480+
}
481+
if (flipVertical) {
482+
rotatedTex = new float[]{
483+
rotatedTex[0], flip2(rotatedTex[1]),
484+
rotatedTex[2], flip2(rotatedTex[3]),
485+
rotatedTex[4], flip2(rotatedTex[5]),
486+
rotatedTex[6], flip2(rotatedTex[7]),
487+
};
488+
}
489+
return rotatedTex;
490+
}
491+
492+
493+
private static float flip2(final float i) {
494+
if (i == 0.0f) {
495+
return 1.0f;
496+
}
497+
return 0.0f;
498+
}
453499
}

libWSLive/src/main/java/me/lake/librestreaming/core/RESHardVideoCore.java

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.annotation.TargetApi;
44
import android.graphics.Bitmap;
5+
import android.graphics.Matrix;
56
import android.graphics.SurfaceTexture;
67
import android.hardware.Camera;
78
import android.media.MediaCodec;
@@ -62,6 +63,10 @@ public class RESHardVideoCore implements RESVideoCore {
6263
private boolean isStreaming = false;
6364
private int loopingInterval;
6465

66+
private boolean isEnableMirror;
67+
private boolean isEnablePreviewMirror;
68+
private boolean isEnableStreamMirror;
69+
6570
public RESHardVideoCore(RESCoreParameters parameters) {
6671
resCoreParameters = parameters;
6772
lockVideoFilter = new ReentrantLock(false);
@@ -247,6 +252,13 @@ public void takeScreenShot(RESScreenShotListener listener) {
247252
}
248253
}
249254

255+
256+
public void setMirror(boolean isEnableMirror,boolean isEnablePreviewMirror,boolean isEnableStreamMirror) {
257+
this.isEnableMirror = isEnableMirror;
258+
this.isEnablePreviewMirror = isEnablePreviewMirror;
259+
this.isEnableStreamMirror = isEnableStreamMirror;
260+
}
261+
250262
@Override
251263
public void setVideoChangeListener(RESVideoChangeListener listener) {
252264
synchronized (syncResVideoChangeListener) {
@@ -470,6 +482,11 @@ public void handleMessage(Message msg) {
470482

471483

472484
private void drawSample2DFrameBuffer(SurfaceTexture cameraTexture) {
485+
if(isEnableMirror){
486+
screenTextureVerticesBuffer = GLHelper.adjustTextureFlip(isEnablePreviewMirror);
487+
mediaCodecTextureVerticesBuffer = GLHelper.adjustTextureFlip(isEnableStreamMirror);
488+
}
489+
473490
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, sample2DFrameBuffer);
474491
GLES20.glUseProgram(offScreenGLWapper.cam2dProgram);
475492
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
@@ -505,7 +522,7 @@ private void drawOriginFrameBuffer() {
505522
GLHelper.enableVertex(offScreenGLWapper.camPostionLoc, offScreenGLWapper.camTextureCoordLoc,
506523
shapeVerticesBuffer, cameraTextureVerticesBuffer);
507524
}
508-
GLES20.glViewport(0, 0, resCoreParameters.videoWidth, resCoreParameters.videoHeight);
525+
GLES20.glViewport(0, 0, resCoreParameters.previewVideoHeight, resCoreParameters.previewVideoWidth);
509526
doGLDraw();
510527
GLES20.glFinish();
511528
GLHelper.disableVertex(offScreenGLWapper.camPostionLoc, offScreenGLWapper.camTextureCoordLoc);
@@ -615,15 +632,21 @@ private void checkScreenShot() {
615632
if (resScreenShotListener != null) {
616633
Bitmap result = null;
617634
try {
618-
IntBuffer pixBuffer = IntBuffer.allocate(resCoreParameters.videoWidth * resCoreParameters.videoHeight);
619-
GLES20.glReadPixels(0, 0, resCoreParameters.videoWidth, resCoreParameters.videoHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, pixBuffer);
635+
IntBuffer pixBuffer = IntBuffer.allocate(resCoreParameters.previewVideoHeight * resCoreParameters.previewVideoWidth);
636+
GLES20.glReadPixels(0, 0, resCoreParameters.previewVideoHeight, resCoreParameters.previewVideoWidth, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, pixBuffer);
620637
int[] glPixel = pixBuffer.array();
621-
int[] argbPixel = new int[resCoreParameters.videoWidth * resCoreParameters.videoHeight];
622-
ColorHelper.FIXGLPIXEL(glPixel, argbPixel, resCoreParameters.videoWidth, resCoreParameters.videoHeight);
638+
int[] argbPixel = new int[resCoreParameters.previewVideoHeight * resCoreParameters.previewVideoWidth];
639+
ColorHelper.FIXGLPIXEL(glPixel, argbPixel, resCoreParameters.previewVideoHeight, resCoreParameters.previewVideoWidth);
623640
result = Bitmap.createBitmap(argbPixel,
624-
resCoreParameters.videoWidth,
625-
resCoreParameters.videoHeight,
641+
resCoreParameters.previewVideoHeight,
642+
resCoreParameters.previewVideoWidth,
626643
Bitmap.Config.ARGB_8888);
644+
645+
if(isEnableMirror && isEnablePreviewMirror){
646+
Matrix mx = new Matrix();
647+
mx.setScale(-1, 1); //产生镜像
648+
result = Bitmap.createBitmap(result,0,0,result.getWidth(),result.getHeight(),mx,true);
649+
}
627650
} catch (Exception e) {
628651
LogTools.trace("takescreenshot failed:", e);
629652
} finally {

libWSLive/src/main/java/me/lake/librestreaming/core/RESSoftVideoCore.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,4 +544,9 @@ private void unlockVideoFilter() {
544544
public void setVideoEncoder(final MediaVideoEncoder encoder) {
545545

546546
}
547+
548+
@Override
549+
public void setMirror(boolean isEnableMirror, boolean isEnablePreviewMirror, boolean isEnableStreamMirror) {
550+
551+
}
547552
}

0 commit comments

Comments
 (0)