viewer端拉流日志是这样的:

 07:19:26.263 VERBOSE sampleAudioFrameHandler(): Audio Frame received. TrackId: 140092278368896, Size: 160, Flags 3210729368
2025-06-12 07:19:26.283 VERBOSE sampleAudioFrameHandler(): Audio Frame received. TrackId: 140092278368896, Size: 160, Flags 3210729368
2025-06-12 07:19:26.298 VERBOSE sampleVideoFrameHandler(): Video Frame received. TrackId: 140092278368896, Size: 4458, Flags 3210729368
2025-06-12 07:19:26.303 VERBOSE sampleAudioFrameHandler(): Audio Frame received. TrackId: 140092278368896, Size: 160, Flags 3210729368
2025-06-12 07:19:26.323 VERBOSE sampleAudioFrameHandler(): Audio Frame received. TrackId: 140092278368896, Size: 160, Flags 3210729368
2025-06-12 07:19:26.338 VERBOSE sampleVideoFrameHandler(): Video Frame received. TrackId: 140092278368896, Size: 263, Flags 3210729368
2025-06-12 07:19:26.343 VERBOSE sampleAudioFrameHandler(): Audio Frame received. TrackId: 140092278368896, Size: 160, Flags 3210729368
2025-06-12 07:19:26.363 VERBOSE sampleAudioFrameHandler(): Audio Frame received. TrackId: 140092278368896, Size: 160, Flags 3210729368
2025-06-12 07:19:26.378 VERBOSE sampleVideoFrameHandler(): Video Frame received. TrackId: 140092278368896, Size: 314, Flags 3210729368
2025-06-12 07:19:26.383 VERBOSE sampleAudioFrameHandler(): Audio Frame received. TrackId: 140092278368896, Size: 160, Flags 3210729368
2025-06-12 07:19:26.403 VERBOSE sampleAudioFrameHandler(): Audio Frame received. TrackId: 140092278368896, Size: 160, Flags 3210729368
2025-06-12 07:19:26.418 VERBOSE sampleVideoFrameHandler(): Video Frame received. TrackId: 140092278368896, Size: 825, Flags 3210729368
2025-06-12 07:19:26.423 VERBOSE sampleAudioFrameHandler(): Audio Frame received. TrackId: 140092278368896, Size: 160, Flags 3210729368
2025-06-12 07:19:26.443 VERBOSE sampleAudioFrameHandler(): Audio Frame received. TrackId: 140092278368896, Size: 160, Flags 3210729368
2025-06-12 07:19:26.458 VERBOSE sampleVideoFrameHandler(): Video Frame received. TrackId: 140092278368896, Size: 1066, Flags 3210729368
2025-06-12 07:19:26.463 VERBOSE sampleAudioFrameHandler(): Audio Frame received. TrackId: 140092278368896, Size: 160, Flags 3210729368
2025-06-12 07:19:26.484 VERBOSE sampleAudioFrameHandler(): Audio Frame received. TrackId: 140092278368896, Size: 160, Flags 3210729368
2025-06-12 07:19:26.498 VERBOSE sampleVideoFrameHandler(): Video Frame received. TrackId: 140092278368896, Size: 1029, Flags 3210729368
2025-06-12

如何从这样的拉流日志中推算出视频帧率和音频帧率呢?

首先要获取足够的样本

比如获取300条视频帧日志:

grep -i 'Video Frame received' viewer_channel_index_20250612_071920_039.log | head -n 300
  • 先用 grep 过滤出所有匹配行
  • 再用 head -n 300 只显示前300条结果

之后在上面命令得到的结果基础上,过滤出每行日志前面的日期和时间,例如,2025-06-12 07:19:42.138

grep -i 'Video Frame received' viewer_channel_index_20250612_071920_039.log | head -n 300 | awk '{print $1, $2}'
  • awk ‘{print $1, $2}’ 打印每行的第1和第2列,也就是日期和时间(空格分隔)

得到的结果是:

2025-06-12 07:19:38.738
2025-06-12 07:19:38.778
...
2025-06-12 07:19:50.698

计算步骤

第一帧时间:07:19:38.738
最后一帧时间:07:19:50.698

先把时间转换成秒:
07:19:38.738 → 73600 + 1960 + 38.738 = 26378.738秒
07:19:50.698 → 73600 + 1960 + 50.698 = 26390.698秒

时间差 = 26390.698 - 26378.738 = 11.96秒

我取了 300 条时间戳,所以,帧数 = 300

帧率 = 帧数 / 时间差 = 300 / 11.96 ≈ 25.08 fps

据此推算视频流的平均帧率大约是 25 fps。

如果视频帧率是 25 fps(frames per second),那么每一帧之间的理论时间间隔为:

1 秒 / 25= 0.04= 40 毫秒

帧率为 25fps → 理想帧间隔是 40ms

允许波动 ±20%:

40ms * 0.8 = 32ms(下限)

40ms * 1.2 = 48ms(上限)

所以,

lower=32
upper=48

是一个 合理、宽容但不松散 的时间间隔判断范围,可以用来判断是否稳定达到了 25fps。

音频帧的日志取样为:

07:19:38.699
07:19:38.719
07:19:38.740
07:19:38.760
07:19:38.780
07:19:38.800
...

音频帧之间的间隔大多为 20ms 左右,所以:

1 秒 / 0.02 秒(20ms) = 50 帧每秒

音频帧率 ≈ 50 fps

允许波动 ±20%:

20ms * 0.8 = 16ms(下限)

20ms * 1.2 = 24ms(上限)

所以,

lower=16
upper=24

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/87370.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/87370.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/87370.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue.js——组件基础

目录 选项式API和组合式API 选项式API 组合式API 语法糖 选项式API和组合式API的关系 生命周期函数 组合式API的生命周期函数 选项式API的生命周期函数 组件的注册和引用 注册组件 全局注册 局部注册 引用组件 解决组件之间的样式冲突 scoped属性 深度选择器 …

Yii2 安装-yii2-imagine

#composer 安装-如已安装跳过 php -r "copy(https://install.phpcomposer.com/installer, composer-setup.php);" php composer-setup.php sudo mv composer.phar /usr/local/bin/composer#执行安装 composer require --prefer-dist yiisoft/yii2-imagine#报错 Updat…

C#程序设计简介

一、发展历史 C#的主要作者是丹麦计算机科学家安德斯海尔斯伯格(Anders Hejlsberg),他是该语言的首席设计师,同时也是Turbo Pascal(Pascal 语言编译器)、Delphi(由 Borland(后被 Em…

JavaWeb笔记03

七、Maven1_概述Maven 是专门用于管理和构建 Java 项目的工具,它的主要功能有: 提供了一套标准化的项目结构 提供了一套标准化的构建流程(编译,测试,打包,发布……) 提供了一套依赖管理机制1.标准化的项目结…

AIGC自我介绍笔记

AIGC(人工智能生成内容)项目是指利用人工智能技术(如深度学习、生成对抗网络、大规模预训练模型等)自动生成文本、图像、音频、视频等多模态内容的系统性工程。这类项目通过算法模型学习海量数据,实现内容的自动化、个…

从docker-compose快速入门Docker

不得不提容器化技术是未来的一个发展方向,它彻底释放了计算虚拟化的威力,极大提高了应用的运行效率,降低了云计算资源供应的成本!使用 Docker,可以让应用的部署、测试和分发都变得前所未有的高效和轻松!无论…

【BERT_Pretrain】Wikipedia_Bookcorpus数据预处理(二)

上一篇介绍了wikipedia和bookcopus数据集,这一篇主要讲一下如何预处理数据,使其可以用于BERT的Pretrain任务MLM和NSP。 MLM是类似于完形填空的任务,NSP是判断两个句子是否连着。因此数据预处理的方式不同。首先,拿到原始数据集&a…

人工智能-基础篇-14-知识库和知识图谱介绍(知识库是基石、知识图谱是增强语义理解的知识库、结构化数据和非结构化数据区分)

在人工智能(AI)领域,知识图谱(Knowledge Graph)和知识库(Knowledge Base)是两种重要的知识表示和管理技术,它们的核心目标是通过结构化的方式组织信息,从而支持智能系统的…

7月1日作业

思维导图 一、将当前的时间写入到time.txt的文件中,如果ctrlc退出之后,在再次执行支持断点续写 1.2022-04-26 19:10:20 2.2022-04-26 19:10:21 3.2022-04-26 19:10:22 //按下ctrlc停止,再次执行程序 4.2022-04-26 20:00:00 5.2022-04-26 20:0…

DHCP中继及动态分配

DHCP中继 在多 VLAN 网络中为什么不能直接用 DHCP? 比如你现在的网络是:PC 在 VLAN10、VLAN20 中DHCP服务器(Router0)在另一个网段(比如 192.168.100.0/24)PC 的 DHCP Discover 是广播,无法跨越…

ROS 概述与环境搭建

1. ROS 简介 1.1 ROS 诞生背景 机器人是一种高度复杂的系统性实现,机器人设计包含了机械加工、机械结构设计、硬件设计、嵌入式软件设计、上层软件设计....是各种硬件与软件集成,甚至可以说机器人系统是当今工业体系的集大成者。 机器人体系是相当庞大的…

mac python3.13 selenium安装使用

一、安装 # 进入虚拟环境 workon xxxx pip install selenium二、安装驱动 查询自己浏览器版本 /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --versionGoogle Chrome 138.0.7204.93下载对应的驱动,其他版本 sudo mv ~/Downloads/chromedr…

AI 开发平台:中小企业的创新破局点在哪里?

在浙江义乌的一个小商品加工厂里,老板王建国最近有点烦。订单量忽高忽低,原材料价格波动不定,他想通过数据分析提前规划生产,却苦于没有专业的技术团队;在广东东莞的一家电子配件公司,业务员李娜每天要处理…

.NET 8.0 Redis 教程

一、环境准备 1. 安装 Redis 服务器 Windows/macOS/Linux:使用 Docker 快速部署 bash docker run -d --name redis -p 6379:6379 redisLinux:直接安装 bash sudo apt-get install redis-server sudo systemctl start redis-server2. 创建 .NET 项目 b…

2025年游戏鼠标推荐,游戏鼠标推荐,打CSGO(罗技、雷蛇、卓威、ROG、漫步者、赛睿、达尔优)

可能很多人对于游戏鼠标的了解还是不够深,会有很多疑问,比如:“游戏鼠标和办公鼠标的区别”、“游戏鼠标无线好还是有线好”等等一系列的问题,本文将会介绍游戏鼠标领域处于领先地位的几个厂家:罗技鼠标、雷蛇鼠标、赛…

OpenCV CUDA模块设备层-----在 GPU上高效地执行两个uint类型值的最小值比较函数vmin2()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 OpenCV 的CUDA模块(cudev) 中的一个设备端内联函数,用于在GPU上高效地执行两个uint类型值的最小值比较。 该函…

Web3与传统网络安全模型对比:关键差异解析

随着互联网技术的飞速发展,Web3的概念逐渐成为人们关注的焦点。Web3代表着一个更加去中心化、安全和用户友好的网络环境。与传统的网络安全模型相比,Web3在多个方面展现出了其独特的优势和特点。本文将深入探讨Web3与传统网络安全模型之间的关键差异。 …

FLAN:微调语言模型是 Zero-Shot 学习者

摘要 本文探讨了一种简单的方法来提升语言模型的零样本学习能力。我们展示了指令微调——即在通过指令描述的数据集集合上对语言模型进行微调——能够显著提升模型在未见任务上的零样本表现。 我们以一个拥有1370亿参数的预训练语言模型为基础,在60多个通过自然语…

springboot中的事件发布和监听

事件定义 创建一个自定义事件类 UserLoginEvent,继承 ApplicationEvent,用于携带用户登录信息: import org.springframework.context.ApplicationEvent;public class UserLoginEvent extends ApplicationEvent { //关键点1:ext…

“开源双轨架构+40亿参数扩散Transformer——ComfyUI-OmniGen2本地部署教程:重塑多模态生成的效率边界!

一、简介 OmniGen2 是由北京智源研究院最新推出的一个强大、高效的开源多模态生成模型。与 OmniGen v1 不同,OmniGen2 具有两种不同的文本和图像模态解码路径,利用非共享参数和解耦的图像分词器。OmniGen2 在四个主要功能方面具有竞争力的性能&#xff…