使用Qt5.4录制视频

Recording Video using Qt5.4

我正在构建一个跨平台应用程序来记录多媒体文件以供后续处理。这是基于继承的应用程序,我无法使用替代库重写。

我当前的问题是 QMediaRecorder 显然没有将视频文件保存到本地驱动器上 - 我暂时将要保存为 banana.mov 的文件硬编码到用户根文件夹中.

执行时,未保存输出文件。

我已经尝试按照建议强制解决here and have seen that others have had issues recording from windows but OSX was fine

开发环境 OSX 10.10 with Qt5.4(同样的问题也发生在 Windows 8.1 机器上,使用 Qt5.3)

code on Github 基于相机示例,在尝试识别和重现问题时添加了额外的调试代码。

在调查过程中,QMediaRecorder::​supportedAudioCodecsQMediaRecorder::supportedVideoCodecs 两个 return 空列表。 OSX 构建和 Windows 环境都会发生这种情况。

调试输出如下:

Status change SIGNAL 'The recorder is initializing.'
Output location file:~/banana.mov
2015 01 05 14:59:58.111 Number of supported AUDIO Codecs 0
2015 01 05 14:59:58.111 Number of Audio sample rates 0
2015 01 05 14:59:58.111 Number of Video Codecs 0
2015 01 05 14:59:58.111 Number of Video Frame Rates 0
2015 01 05 14:59:58.111 Number of Containers 0
Location Changed SIGNAL 'file:~/banana.mov'
State change SIGNAL 'The recording is requested.'
Recording should have started
2015 01 05 14:59:58.111 Number of supported AUDIO Codecs 0
2015 01 05 14:59:58.111 Number of Audio sample rates 0
2015 01 05 14:59:58.111 Number of Video Codecs 0
2015 01 05 14:59:58.111 Number of Video Frame Rates 0
2015 01 05 14:59:58.111 Number of Containers 0
Status change SIGNAL 'Recording is requested but not active yet.'

我觉得我错过了一些非常明显的东西,我只是还没有发现它!

编辑 1 很明显,状态是 Recording is requested but not active yet 而不是 Recording is active。我目前正在尝试弄清楚为什么 录制没有开始。

edit 2 录音机示例确实录制并保存了一个音频文件。看起来 QMediaRecorder not return 可用音频编解码器列表,但 QAudioRecorder does return 音频列表编解码器。我在使用 Qt5.3 的 Windows 8.1 和使用 Qt 5.4

的 OSX 上得到了相同的结果

您很可能正在查看 OS 特定工件,而不是 QT 的核心问题。

这个问题我在很多工具包和框架中见过很多次,这让我很害怕,因为还没有人想出一个优雅的解决方案。

问题的基础

大多数操作系统对关键系统文件实施某种保护。

在 *nix 下,这是 user/group 权限系统的形式,在 windows 下类似,但有 UAC(用户访问控制)子系统。

归根结底,您通常不能随便选择一个任意位置来写入文件,而不是先寻求 API 中的各种安全机制和机制的许可 [=79] =] 这样做。

问题的后半部分来自于变量扩展。

在 *nix 中,波浪字符 '~' 由 shell 扩展,表示用户主目录。

当我们说 shell 时,我们指的是 bash、tch、csh 或您的 运行 应用所在的任何环境。

在这个组合中,我们还将桌面环境也放在一起,因为大多数东西,如 Kde、Gnome、Unity 或其他正在使用的东西,都有某种操作系统调用,当“~”是传递给它,知道将其转换为“/home/neil/”或任何需要扩展的内容。

Windows 也有类似的功能,你可以拨打 OS 电话并说 'Hey mr operating system, where are my user folders stored',它会很乐意回复 'c:\users\'

为什么问题会以这种方式出现

仅仅是因为当您自己负责创建路径字符串时,在您自己的应用程序中,事情通常不会传递给这些各种 OS 扩展和安全许可的调用,您几乎必须确保你是那个叫他们的人。

此规则的例外情况是,如果您使用 *nix 哲学的小工具组合来完成一项工作。在这种情况下,您通常会将结果传递给基于 shell 的程序,因为它是 运行 通过 shell 然后知道如果它看到 '~' 它必须扩展它。

因为你使用直接文件访问,管理你自己的文件路径,当你认为你在哪里写入'\home\neil\file.mov'时,你实际上试图在其中写入一个名为 'file.mov' 的文件您的应用所在的当前文件夹 运行,在一个名为“~”的文件夹中,我愿意进入该文件夹不存在。

除此之外,许多框架(QT 也不例外)旨在隐藏和抽象掉所有丑陋的细节,很有可能它消耗了生成的 OS 异常当您实际尝试写入文件时,如果没有,那么您的应用很可能会因某种异常对话框而崩溃。

如何解决问题

您可以采用 3 种方法来缓解这种情况。

  • 1) 您可以对路径进行硬编码,也就是说您可以明确告诉应用程序始终将您的文件存储在'/home/neil/videos/blah.mov',这但是有一个缺点,即应用程序的每个用户都需要自定义构建,因为它不太可能 'person2' 对'neil 的主目录具有写权限。

  • 2) 您可以内置功能,为用户提供一个对话框并询问他们希望将文件保存在何处。由于您使用像 QT 这样的东西应该非常容易,这些 UI 工具包中的大多数都具有内置功能,可以轻松地为用户提供这样的体验。

  • 3)你可以看看你的框架或者底层OS有没有调用你询问当前用户是谁,他们的home目录在哪里,你就可以使用返回的信息动态构建类似于选项 1 中的静态补丁。以这种方式执行操作可确保应用程序自动适应其环境,而不管用户如何。

就我个人而言,我通常在开发过程中采用选项 1,然后在开发完成后切换到数字 2,我很少在基于桌面的软件中使用数字 3。

当所讨论的应用程序设计为执行单个作业时,我经常使用选项 3,例如转换文件以供另一个进程使用,或为服务器生成一些输出以显示在网页中等等

对于你来说,现在作为这个问题的解决方案,选项 1 是你最好的选择。

为了补充 Shawty 的精彩回答,我发现 Qt 不支持在 Windows http://doc.qt.io/qt-5/qtmultimedia-windows.html

上录制

这可能会有帮助https://github.com/kibsoft/QtMEL