我正在使用以下ffmpeg库录制方形视频。 Square Video使用音频成功录制,但现在我想在视频上添加水印,但我的应用程序崩溃并出现错误。请帮助我如何在录制视频时添加水印。
Gradle依赖
compile(group: 'org.bytedeco', name: 'javacv-platform', version: '1.3') {
exclude group: 'org.bytedeco.javacpp-presets'
}
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '3.2.1-1.3'
compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '3.2.1-1.3', classifier: 'android-arm'
我正在使用以下代码在录制视频时添加水印
// add water mark
String imgPath = audioPath + "jodelicon.png";
String watermark = "movie=" + imgPath + " [logo];[in][logo]overlay=0:0:1:format=rgb [out]";
filters.add(watermark);
完整代码
class VideoRecordThread extends Thread {
private boolean isRunning;
@Override
public void run() {
List<String> filters = new ArrayList<>();
// Transpose
String transpose = null;
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(mCameraId, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
switch (info.orientation) {
case 270:
// transpose = "transpose=clock_flip"; // Same as preview display
transpose = "transpose=cclock"; // Mirrored horizontally as preview display
break;
case 90:
// transpose = "transpose=cclock_flip"; // Same as preview display
transpose = "transpose=clock"; // Mirrored horizontally as preview display
break;
}
} else {
switch (info.orientation) {
case 270:
transpose = "transpose=cclock";
break;
case 90:
transpose = "transpose=clock";
break;
}
}
if (transpose != null) {
filters.add(transpose);
}
// Crop (only vertically)
int width = previewHeight;
int height = width * videoHeight / videoWidth;
String crop = String.format("crop=%d:%d:%d:%d",
width, height,
(previewHeight - width) / 2, (previewWidth - height) / 2);
filters.add(crop);
// Scale (to designated size)
String scale = String.format("scale=%d:%d", videoHeight, videoWidth);
filters.add(scale);
// add water mark
String imgPath = audioPath + "jodelicon.png";
String watermark = "movie=" + imgPath + " [logo];[in][logo]overlay=0:0:1:format=rgb [out]";
filters.add(watermark);
FFmpegFrameFilter frameFilter = new FFmpegFrameFilter(TextUtils.join(",", filters),
previewWidth, previewHeight);
frameFilter.setPixelFormat(avutil.AV_PIX_FMT_NV21);
frameFilter.setFrameRate(frameRate);
try {
frameFilter.start();
} catch (FrameFilter.Exception e) {
e.printStackTrace();
}
isRunning = true;
FrameToRecord recordedFrame;
while (isRunning || !mFrameToRecordQueue.isEmpty()) {
try {
recordedFrame = mFrameToRecordQueue.take();
} catch (InterruptedException ie) {
ie.printStackTrace();
try {
frameFilter.stop();
} catch (FrameFilter.Exception e) {
e.printStackTrace();
}
break;
}
if (mFrameRecorder != null) {
long timestamp = recordedFrame.getTimestamp();
if (timestamp > mFrameRecorder.getTimestamp()) {
mFrameRecorder.setTimestamp(timestamp);
}
long startTime = System.currentTimeMillis();
// Frame filteredFrame = recordedFrame.getFrame();
Frame filteredFrame = null;
try {
frameFilter.push(recordedFrame.getFrame());
filteredFrame = frameFilter.pull();
} catch (FrameFilter.Exception e) {
e.printStackTrace();
}
try {
mFrameRecorder.record(filteredFrame);
} catch (FFmpegFrameRecorder.Exception e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
long processTime = endTime - startTime;
mTotalProcessFrameTime += processTime;
Log.d(LOG_TAG, "This frame process time: " + processTime + "ms");
long totalAvg = mTotalProcessFrameTime / ++mFrameRecordedCount;
Log.d(LOG_TAG, "Avg frame process time: " + totalAvg + "ms");
}
Log.d(LOG_TAG, mFrameRecordedCount + " / " + mFrameToRecordCount);
mRecycledFrameQueue.offer(recordedFrame);
}
}
public void stopRunning() {
this.isRunning = false;
if (getState() == WAITING) {
interrupt();
}
}
public boolean isRunning() {
return isRunning;
}
}
logcat错误
android A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x18 in tid 320 (Thread-24542)