2

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

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

执行时,不会保存输出文件。

我已尝试按照此处的建议强制解决,并且看到其他人在从 Windows 录制时遇到问题,但 OSX很好

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

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

在调查时,QMediaRecorder::​supportedAudioCodecsQMediaRecorder::supportedVideoCodecs都返回空列表。这发生在 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。我目前正在尝试找出录制尚未开始的原因。

编辑 2录音机示例确实记录并保存了一个音频文件。看起来 QMediaRecorder没有返回可用音频编解码器的列表,但 QAudioRecorder确实返回了音频编解码器的列表。我在使用 Qt5.3 的 Windows 8.1 和使用 Qt 5.4 的 OSX 上都得到了相同的结果

4

2 回答 2

2

您很可能正在查看特定于操作系统的工件,而不是 QT 的核心问题。

我在这么多工具包和框架中多次看到这个问题,这让我感到害怕,以至于还没有人想出一个优雅的解决方案。

问题的基础

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

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

这归结为,您通常不能只选择任意位置来写入文件,而不是首先寻求操作系统中各种安全 API 和机制的许可才能这样做。

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

在 *nix 中,特别是波浪号字符 '~' 被 shell 扩展为表示用户主目录。

当我们说 shell 时,我们的意思是 bash、tch、csh 或您运行应用程序的任何环境。

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

Windows 也有类似的功能,您可以通过调用操作系统并说“嘿先生操作系统,我的用户文件夹存储在哪里”,它会很高兴地回复“c:\users\”之类的内容

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

仅仅因为当您自己负责创建路径字符串时,在您自己的应用程序中,通常不会将事物传递给这些各种操作系统调用以进行扩展和安全许可,因此您几乎必须确保调用它们的人。

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

因为您使用直接文件访问,当您认为您在哪里写入“\home\neil\file.mov”时管理您自己的文件路径,实际上您正在尝试在当前文件夹中写入一个名为“file.mov”的文件您的应用程序正在从一个名为“〜”的文件夹中运行,我愿意这样做不存在。

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

如何解决问题

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

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

  • 2)您可以内置功能,为用户提供一个对话框并询问他们希望将文件保存在哪里。由于您使用 QT 之类的东西应该很容易,这些 UI 工具包中的大多数都内置了功能,可以轻松地向用户展示这种体验。

  • 3)你可以找出你的框架或底层操作系统是否有任何要求你询问当前用户是谁,以及他们的主目录在哪里,然后你可以使用返回的信息来动态构建一个类似于中的静态补丁选项 1. 以这种方式做事可确保应用程序自动适应其环境,而与用户无关。

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

对我来说,选项 3 通常用于相关应用程序旨在完成一项工作时,例如转换文件以供另一个进程使用,或为服务器生成一些输出以显示在网页中等。

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

于 2015-01-07T15:48:36.850 回答
0

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

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

于 2015-10-22T10:33:16.213 回答