yasea
yasea copied to clipboard
How to add an overlay image to the Live Stream ??
You can create a bitmap object using Bitmap
class library. Search how can make watermark effect in Android.
大神,我要加个时间水印的话怎么做,没思路啊,能写个例子吗?拜托了
Hello, do you have an example or instructions where you add a watermark to the stream? I can get it to display on top of the video by overriding the onDraw function and creating a thread that draws the canvas, but it shows a black screen and it doesn't show on the sent rtmp stream. Thank you!
@javlae Finally, i found a solution to this issue, just add this code to SrcCameraView into onPreviewFrame method :D
Bitmap bitmap,b,ov;
Drawable myDrawable = getResources().getDrawable(R.drawable.logo);
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (mIsEncoding) {
YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, mPreviewWidth, mPreviewHeight, null);
ByteArrayOutputStream os = new ByteArrayOutputStream();
yuvImage.compressToJpeg(new Rect(0,0,yuvImage.getWidth(),yuvImage.getHeight()), 100,os);
byte[] jpegByteArray = os.toByteArray();
bitmap = BitmapFactory.decodeByteArray(jpegByteArray, 0, jpegByteArray.length);
b = drawableToBitmap(myDrawable);
ov=overlay(bitmap,b);
mYuvPreviewFrame=getNV21(mPreviewWidth,mPreviewHeight,ov);
mPrevCb.onGetYuvFrame(mYuvPreviewFrame);
camera.addCallbackBuffer(mYuvPreviewFrame);
}
}
//getNV21 from a bitmap
byte [] getNV21(int inputWidth, int inputHeight, Bitmap scaled) {
int [] argb = new int[inputWidth * inputHeight];
scaled.getPixels(argb, 0, inputWidth, 0, 0, inputWidth, inputHeight);
byte [] yuv = new byte[inputWidth*inputHeight*3/2];
encodeYUV420SP(yuv, argb, inputWidth, inputHeight);
scaled.recycle();
return yuv;
}
void encodeYUV420SP(byte[] yuv420sp, int[] argb, int width, int height) {
final int frameSize = width * height;
int yIndex = 0;
int uvIndex = frameSize;
int a, R, G, B, Y, U, V;
int index = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
a = (argb[index] & 0xff000000) >> 24; // a is not used obviously
R = (argb[index] & 0xff0000) >> 16;
G = (argb[index] & 0xff00) >> 8;
B = (argb[index] & 0xff) >> 0;
// well known RGB to YUV algorithm
Y = ( ( 66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
U = ( ( -38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
V = ( ( 112 * R - 94 * G - 18 * B + 128) >> 8) + 128;
// NV21 has a plane of Y and interleaved planes of VU each sampled by a factor of 2
// meaning for every 4 Y pixels there are 1 V and 1 U. Note the sampling is every other
// pixel AND every other scanline.
yuv420sp[yIndex++] = (byte) ((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));
if (j % 2 == 0 && index % 2 == 0) {
yuv420sp[uvIndex++] = (byte)((V<0) ? 0 : ((V > 255) ? 255 : V));
yuv420sp[uvIndex++] = (byte)((U<0) ? 0 : ((U > 255) ? 255 : U));
}
index ++;
}
}
}
//convert drawable to Bitmap
public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_4444); // Single color bitmap will be created of 1x1 pixel
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
//overlay two bitmap
private Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
canvas.drawBitmap(bmp1, new Matrix(), paint);
canvas.drawBitmap(bmp2, new Matrix(), paint);
return bmOverlay;
}
@Doss12 ONE THOUSAND COOKIES TO YOU MY FRIEND!! The only issue I have is that the image is rotated and flipped, but that should be an easy fix :)
Thank you!
@javlae Let me know when you fix that ;)
@Doss12 I have fixed it by playing with the image dimensions and the rotation. Now it is perfectly positioned on the video stream, but the problem now is that the stream got really bad FPS due to all the processing (event down to 2 frames per second). I am trying to work on optimization, but so far no luck :(
yess i agree with you on the fact that the processing is too long but temporaly it's the only solution that i have found :3
Yeah, me too. I wonder how these guys did it: https://play.google.com/store/apps/details?id=com.vaultmicro.camerafi.live&hl=en
@Doss12 I think the code is changed. how should the new code be approached. Requirements are the same, I need a logo like say 'hbo' at the top left corner of the preview as well as the live video. I am not at all experienced in dealing with this. please help asap
Doss12 : please could you tell me more how did you get the view into the stream? i tried your code but i didn't figure out how to use it? could you give me a sample or a demo? thx
@Doss12 Hey I can not find onPreviewFrame method in SrcCameraView class. Can you help me here?
can you please share SrcCameraView class for same?
libpng
is all you need.
hi,why I can't find SrcCameraView calss,only find SrsCameraView class,and I can't find mPrevCb.onGetYuvFrame,have the code changed?
Why not try libpng
sorry,Could you please tell me more about it? I don't know what is the relationship between srcCameraView and libpng。thank 'you
You might use libpng
in libenc.cc
for image preprocessing.