- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想从文件中提取视频的帧大小。为此,我通过 bash shell 启动了一个 ffmpeg 命令,我想提取输出。此命令在 bash shell 中运行良好,并根据需要返回输出。
ffprobe -v error -count_frames -of flat=s=_ -select_streams v:0 -show_entries stream=nb_read_frames /home/peter/DA/videos/IMG-2014-1-10-10-4-37.avi
我想通过C++调用它并读出结果。我使用带有 GCC 4.8 编译器的 IDE Qt 4.8.6。
对于我的代码,我使用这个模板:
executing shell command with popen
并根据我的要求将其更改为
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
int main()
{
FILE* pipe = popen("echo $(ffprobe -v error -count_frames -of flat=s=_ -select_streams v:0 -show_entries stream=nb_read_frames /home/peter/DA/videos/IMG-2014-1-10-10-4-37.avi)", "r");
if(!pipe)
{
cout << "error" << endl;
return 1;
}
char* buffer = new char[512];
string result;
fgets(buffer, sizeof(buffer), pipe) ;
while(!feof(pipe))
{
if(fgets(buffer, sizeof(buffer), pipe) != NULL)
{
cout << buffer << endl;
result += buffer;
}
}
pclose(pipe);
cout << result<< endl;
return 0;
}
Qt 控制台向我返回了这个警告,它正在返回 0:
/home/peter/DA/videos/IMG-2014-1-10-10-4-37.avi: Invalid data found when processing input
并且“管道”是空的。
当我在 shell 中使用 g++ 编译上面的 main.cpp 文件时,它也工作得很好。
最佳答案
旧帖子,但据我所知,这里有两点:
错误“处理输入时发现无效数据”
这是一个 ffprobe 正常的文件处理错误。通常发生在媒体文件中有错误时,它与 c++ 程序无关。
ffprobe 将警告/错误消息写入 stderr
流,但 popen
仅捕获 stdout
流,这就是您的程序无法获取的原因通过管道的错误消息。
如何在我的程序中获取stdout+stderr
popen
允许执行任何 shell 命令,因此我们可以使用它将 stderr
重定向到 stdout
,这样您的程序也可以获得该输出,像这样:
FILE *pipe = popen("ffprobe ... 2>&1");
2>
将 handle#2 输出重定向到当前 &1
handle#1 输出(#1=stdout
,#2=标准错误
).
绝对不需要执行 FILE *pipe = popen("echo $(ffprobe ...)");
,因为最终结果是一样的:注意 $ (...)
返回带有 stdout
命令输出的字符串,echo
打印它。完全多余。
一些改进代码的观察:
当一个字符串太大而无法在一个屏幕宽度内显示时,最好将其分成多行(也许在某种逻辑中将每行内的文本分组),因为这将提高其他人对您代码的阅读能力人(并最终在几个月后由你自己)。
您可以使用 C/C++ 编译器功能执行此操作,该功能连接由空格(换行符、制表符等)分隔的字符串,例如。 "hi ""world"
与编译器的 "hi world"
相同。
当您的程序必须写入错误消息时,请使用 stderr
流。在 C++ 中,它是 std::cerr
而不是 std::cout
。
总是在没有记录器使用时分配空闲内存(每个 new
都必须有一个 delete
)
避免使用 using namespace std;
,而是对您将使用的每个标准实例/类使用 using std::name;
。前任。 using std::string;
,这避免了 future 的问题,特别是在大型程序中。常见错误的示例是 here .通常避免使用 using namespace xxxx;
。
重组您的代码,我们有:
#include <iostream>
#include <stdio.h>
using std::string;
using std::cout;
using std::cerr;
using std::endl;
int main() {
static char ffprobeCmd[] =
"ffprobe " // command
"-v error " // args
"-count_frames "
"-of flat=s=_ "
"-select_streams v:0 "
"-show_entries stream=nb_read_frames "
"/home/peter/DA/videos/IMG-2014-1-10-10-4-37.avi" // file
" 2>&1"; // Send stderr to stdout
FILE *pipe = popen(ffprobeCmd, "r");
if (!pipe) {
perror("Cannot open pipe.");
return 1;
}
char* buffer = new char[512];
string result;
while ((fgets(buffer, sizeof(buffer), pipe)) != NULL) {
result += buffer;
}
// See Note below
int retCode = pclose(pipe);
if (retCode != 0) {
// Program ends with error, and result has the error message
cerr << "retCode: " << retCode << "\nMessage: " << result << endl;
return retCode;
} else {
// Program ends normally, prints: streams_stream_0_nb_read_frames="xxx"
cout << result << endl;
}
delete buffer; // free memory
return 0;
}
注意
pclose
并不是为了返回执行的程序状态代码,但是如果你需要这个值,pclose 在某些 c++ 版本/系统中会这样做,所以检查一下。无论如何,只有在一切正常的情况下它才会为零。
关于c++ - 执行 bash shell 命令并提取输出 --> 无效文件错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31919172/
我有一个接受以下参数的函数: int setvalue(void (*)(void *)); 为了满足参数:void (*)(void *),我创建了这样一个函数: static void *
我有以下代码: typedef void VOID; int f(void); int g(VOID); 在 C 中编译得很好(在 Fedora 10 上使用 gcc 4.3.2)。与 C++ 编译的
这个问题已经有答案了: Is f(void) deprecated in modern C and C++? [duplicate] (6 个回答) 已关闭 7 年前。 B.A.T.M.A.N./A.
我在 ASP.NET Core 3.1 项目上有以下 Identity Server 4 配置: services .AddIdentityServer(y => { y.Events.R
我们有一个 O365 租户,一切都是开箱即用的。租户放置在德国云中,而不是全局 (office.de) 中。我们还开发了一个 Office 插件,使用 OAuth 2.0 授权访问共享点。首先,我们向
我有一个如下所示的路由 routes.MapRoute( name: "Default", url: "{controller}/{action}/{i
我正在尝试使用 OAuth2.0 访问 google 文档。我已经从 Google API 控制台获取了客户端 ID 和 key 。但是当我运行这段代码时,我收到了异常。如果我遗漏了什么,有人可以建议
此代码有效: let mut b: Vec = Vec::with_capacity(a.len()); for val in a.iter() { b.push(val); } 此代码不起作
使用 client_credintials 授权类型请求 EWS oauth2 v2.0 的访问 token 时出现错误。 https://login.microsoftonline.com/tena
我通过 Java 应用程序使用 Google 电子表格时遇到了问题。我创建了应用程序,该应用程序运行了 1 年多,没有任何问题,我什至在 Create Spreadsheet using Google
如何创建 匹配所有无效 Base64 字符的正则表达式?我在堆栈上找到了 [^a-zA-Z0-9+/=\n\r].*$ 但是当我尝试时我得到了带有 - 符号的结果字符串.我根本不知道正则表达式,任何人
我从 Gitlab CI/CD Pipelines 获得错误信息:yaml invalid。问题是由 .gitlab-ci.yml 脚本的第五行引起的: - 'ssh deployer@gita
我有 3 个数据源,设置如下: @Configuration @Component public class DataSourceConfig { @Bean("foo") @Conf
你好,我想用bulkCreate ex 插入数据: [ { "typeId": 5, "devEui": "0094E796CBFCFEF9", "application_name": "Pressu
UIApplicationExitsOnSuspend 不会强制我的应用程序退出。我已经清理过目标、删除了应用程序、重建并重新安装了很多次。 我确实需要退出我的应用程序。 最佳答案 您是否链接了 SD
在 iPhone 配置门户上,显示我的 iPhone 团队配置配置文件无效。有一个“由 Xcode 管理”文本。 “续订”按钮被禁用。 我该如何解决这个问题?谢谢 最佳答案 使用 Xcode 3.2.
好的,所以今天我用我们的“实时”数据库中的新信息更新了我的数据库……从那时起,我的一个表格就出现了问题。如果您需要任何代码,请告诉我,我将对其进行编辑并发布所需的代码... 我有一个报告表格,其中有一
我有一个结构体,其中有一个元素表示为 void (*func)(); 我知道 void 指针通常用于函数指针,但我似乎无法定义该函数。我不断收到取消引用指向不完整类型的指针。我用谷歌搜索了一下但没有结
我正在尝试使用 Coldfusion 9 从 ning 网络获取凭证,所以首先这是测试 api 的 curl 语法: curl -k https://external.ningapis.com/xn/
这个问题已经有答案了: Does C have references? (2 个回答) 已关闭 4 年前。 我正在学习 C 语言引用,这是我的代码: #include int main(void)
我是一名优秀的程序员,十分优秀!