3

Microsoft.WindowsAPICodePack.Shell.ShellFile用来从文件路径获取视频大小(宽度和高度)。

public Size GetVideoSize(string videoFullPath)
{
    if (File.Exists(videoFullPath))
    {
        ShellFile shellFile = ShellFile.FromFilePath(videoFullPath);

        int videoWidth = (int)shellFile.Properties.System.Video.FrameWidth.Value;
        int videoHeight = (int)shellFile.Properties.System.Video.FrameHeight.Value;

        return new Size(videoWidth, videoHeight);
    }
    return Size.Empty;
}

问题是此方法无法检索 m4v 文件的正确大小。你有什么建议吗?我可以使用什么来获得实际的宽度/高度?

示例:我有一个 m4v 视频,其实际尺寸为 856x480

  • 如果我在 Windows 资源管理器中查看文件的属性,大小为 720x480(错误)
  • 如果我在视频播放器中打开视频,视频将以正确的大小呈现,即使视频细节仍显示 720x480 的大小
  • 如果我在 WPF 中的 MediaElement 控件中加载视频,我会通过 获得正确的大小,mediaElement.NaturalVideoWidth, mediaElement.NaturalVideoHeight但问题是我需要在没有任何 WPF 引用的类库中获取大小。
4

1 回答 1

1

这里的关键提示是 856/480 = 1.78,大约等于 16/9 = 1.77,这是宽屏视频的常见纵横比。像素分辨率为 1:1.33 或 1:1.5(例如 640x480 或 720x480)的视频并不罕见,但它意味着以 1:1.77(例如856x480)。这称为变形宽银幕。所以 720x480 可能是视频的正确分辨率,但不是正确的显示尺寸

在窗口中显示变形宽银幕时,视频播放器通常只是保持相同的高度并拉伸宽度以获得正确的显示纵横比。如果是全屏,则宽度和高度都可能会被拉伸,但不会拉伸相同的因子,以便显示宽高比正确,并且视频完全适合屏幕分辨率。

要获得显示尺寸(这似乎是您想要的),我们需要纵横比。幸运的是,用于获取帧宽度和高度的相同元数据属性 API也具有纵横比属性,即System.Video.Horizo​​ntalAspectRatioSystem.Video.VerticalAspectRatio。虽然没有记录,但这些似乎是指像素纵横比,而不是图片显示纵横比。你想要的变形视频是这样的:

int videoWidth = (int)shellFile.Properties.System.Video.FrameWidth.Value;
int videoHeight = (int)shellFile.Properties.System.Video.FrameHeight.Value;
int horizontalAspect = (int)shellFile.Properties.System.Video.HorizontalAspectRatio.Value;
int verticalAspect = (int)shellFile.Properties.System.Video.VerticalAspectRatio.Value;
int displayWidth = videoWidth * horizontalAspect / verticalAspect;
int displayHeight = videoHeight;

在您的情况下,我期望的是 Horizo​​ntalAspect = 53 和 verticalAspect = 45 (或产生类似比率的其他值)。

显示分辨率可能会四舍五入到 16 或 8 像素的精确倍数,因此您可能还需要执行以下操作:

int roundingMultiple = 8;
int displayWidth = videoWidth * horizontalAspect / verticalAspect;
displayWidth = ((displayWidth - 1) / roundingMultiple + 1) * roundingMultiple;

这不是特定于 mkv 文件的;任何容器格式的任何变形视频文件都必须进行相同的处理。

编辑:更改了上面的代码以反映 Horizo​​ntalAspect / verticalAspect 显然是像素纵横比的事实。

于 2012-11-25T12:39:08.800 回答