首先,我正在使用的设备的屏幕尺寸为1080 x 2280 pixels, 19:9 ratio
,这一点很重要,稍后将在问题中进行解释。
几个月前,我问了this个问题。提供的答案非常有效:
"-i", video.mp4, "-i", image.png, "-filter_complex", "[0:v]pad=iw:2*trunc(iw*16/9/2):(ow-iw)/2:(oh-ih)/2[v0];[1:v][v0]scale2ref[v1][v0];[v0][v1]overlay=x=(W-w)/2:y=(H-h)/2[v]", "-map", "[v]", "-map", "0:a", "-c:v", "libx264", "-preset", "ultrafast", "-r", outFPS, output.mp4
实施并发布此代码后不久,我开始收到来自用户的消息,抱怨放置在视频顶部的图像在保存后不在同一位置。
我在命令中注意到触摸板的比率上方设置为16:9
的比率,换句话说,以上内容不适用于屏幕比率为19:9
的设备。
然后我又问了question这个问题,与@Gyan进行了长时间的交谈之后,命令更改为以下内容:
"-i", video.mp4, "-i", image.png, "-filter_complex", "[0:v]scale=iw*sar:ih,setsar=1,pad='max(iw\,2*trunc(ih*9/16/2))':'max(ih\,2*trunc(ow*16/9/2))':(ow-iw)/2:(oh-ih)/2[v0];[1:v][v0]scale2ref[v1][v0];[v0][v1]overlay=x=(W-w)/2:y=(H-h)/2[v]", "-map", "[v]", "-map", "0:a", "-c:v", "libx264", "-preset", "ultrafast", "-r", outFPS, output.mp4
在具有16:9
比率的设备上进行测试是完美的。
现在使用上述设备进行测试,我将命令中的比率替换为以下内容(19/9/2
和9/19/2
):
"-i", video.mp4, "-i", image.png, "-filter_complex", "[0:v]scale=iw*sar:ih,setsar=1,pad='max(iw\,2*trunc(ih*9/19/2))':'max(ih\,2*trunc(ow*19/9/2))':(ow-iw)/2:(oh-ih)/2[v0];[1:v][v0]scale2ref[v1][v0];[v0][v1]overlay=x=(W-w)/2:y=(H-h)/2[v]", "-map", "[v]", "-map", "0:a", "-c:v", "libx264", "-preset", "ultrafast", "-r", outFPS, output.mp4
这是我得到的结果:
我将播放器的背景更改为绿色,以便于查看。蓝线是我要覆盖的图像
原始视频
处理后
以下是上述问题。
这是我想要达到的结果:
您会注意到以下内容:
任何实现上述目标的建议将不胜感激。
我将向用户提供300积分,可以帮助我解决此问题。
编辑1
Here是输入视频,图像和注释部分中要求的预期输出。此设备使用的纵横比为16:9
,屏幕尺寸为1920x1080
。
Here是预期输出的另一个示例(我还包括输入图像和输入视频)。
编辑2
我认为值得一提的是,输入图像将始终是设备屏幕的尺寸/尺寸,因此它也将始终具有与屏幕相同的纵横比。输入视频的大小/尺寸会有所不同。
答案 0 :(得分:0)
首先,我要感谢@Gyan在此问题上的所有帮助。
该问题是由于我没有为具有缺口显示的设备进行设计/规划而引起的。
在我的应用程序中,我隐藏了状态栏,并且在具有缺口显示(并且用户已将其禁用)的设备上,状态栏应位于顶部的黑色栏上。
如果您查看问题Original video
中的图片,您会看到顶部有一个黑条。
我为获得屏幕高度所做的事情如下:
DisplayMetrics displayMetrics = new DisplayMetrics();
WindowManager wm = (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
Display disp = wm.getDefaultDisplay();
disp.getRealMetrics(displayMetrics);
mWidth = disp.getWidth();
mHeight = disp.getHeight();
我认为这可以解决问题,但是问题是,即使隐藏状态栏,在缺口设备上,屏幕尺寸也会是(实际屏幕高度-状态栏)。
换句话说,我将错误的宽高比传递给FFmpeg。
我要做的就是修复它,我添加了一个视图并将其宽度和高度设置为match_parent
。通过这样做,我知道它将始终充满整个屏幕。然后,我使用该视图确定设备的长宽比。
这就是我获得设备的纵横比(视图设置为match_parent
)的方式:
int gcd(int p, int q) {
if (q == 0) return p;
else return gcd(q, p % q);
}
void ratio(int a, int b) {
final int gcd = gcd(a,b);
if(a > b) {
setAspectRatio(a/gcd, b/gcd);
} else {
setAspectRatio(b/gcd, a/gcd);
}
}
void setAspectRatio(int a, int b) {
//public int's
imageAndVideoAspectForScaling = a+"/"+b+"/"+2;
imageAndVideoAspectForScalingb = b+"/"+a+"/"+2;
}
然后我检查设备是纵向还是横向,并进行相应的调整:
肖像:
"[0:v]scale=iw*sar:ih,setsar=1,pad='max(iw\\,2*trunc(ih*"+imageAndVideoAspectForScalingb+"))':'max(ih\\,2*trunc(ow*"+imageAndVideoAspectForScaling+"))':(ow-iw)/2:(oh-ih)/2[v0];[1:v][v0]scale2ref[v1][v0];[v0][v1]overlay=x=(W-w)/2:y=(H-h)/2[v]"
风景:
"[0:v]scale=iw*sar:ih,setsar=1,pad='max(iw\\,2*trunc(ih*"+imageAndVideoAspectForScaling+"))':'max(ih\\,2*trunc(ow*"+imageAndVideoAspectForScalingb+"))':(ow-iw)/2:(oh-ih)/2[v0];[1:v][v0]scale2ref[v1][v0];[v0][v1]overlay=x=(W-w)/2:y=(H-h)/2[v]"