网络播放器

Python制作的精美的一个网络爬虫播放器加本地播放器 Python自制播放器(Spider + Play + More) 阅读详情

作者:afterain
本人最近刚刚把它做完。鉴于现在很多 人在向这方面发展,所以决定把自己 在此期间的一些经验写出来。让后来的同志们少走些弯路。
我的这个事例是通过directshow的例子memfile改写的。如果用于网络的时时播放,会有一些延时问题。具体会在后面说明。我已经把它作成了DLL(实际也是工作的需要 :) ),大家可以在www.feelby.net下载。包括演示例子的源代码。至于DLL中的其他代码,可以参考我原来的文章,可在优快云的开发文档中找到(关键字用“direct”),说明了一些directshow的基本知识和对他的操作。


先说说memfile例子的整体框架。实际上,directshow已经封装好了几个类,CasyncReader和CasyncStream是我们最关心的,CasyncReader已经是个source filter了,而我们只需通过CasyncStream类就可以控制数据了。CasyncStream类很简单,都是一些纯虚函数。我们是继承它,把它的函数完善就行了。


现在把工作的重点放在CasyncStream类。Memfile是继承了它得到自己的类CmemStream。因为这个类有了一些函数的总体框架,所以我就用它做为父类了(当然,完全可以直接从CasyncStream继承)。有三个重要的函数:SetPointer(LONGLONG llPos),Read(PBYTE pbBuffer,DWORD dwBytesToRead,BOOL bAlign,LPDWORD pdwBytesRead)和Size(LONGLONG *pSizeAvailable)。其中重中之重是Read函数,(实际上我已经弃用SetPointer函数了)。所以的数据操作都是在这里完成的。下面通过具体的代码来说明。


参数的说明:
m_pbData                     读写的内存数据指针
m_llLength                   数据的总长度
m_llPosition                 实际读写的内存数据位置指针
m_dwKBPerSec          播放的的速率
由于初期时,操作内存数据指针m_pbData总是出错,所以改用自己的指针。本来是打算用m_llPosition来虚拟个无限大的内存空间(实际就是循环0---max,读前面的数据,刷新后面的,接着读后面的,刷新前面的来达到这效果),可是要烦琐一些,有些临界条件难以判断。所以实际上是我只用了它的参数m_llLength。大家可以通过memfile的源代码来学习m_llPosition+ m_pbData的用途。
m_llLength是个非常重要的参数。如果你要做网络的实时监控,当然不希望播放了几个小时就停了。通过修改它可以达到你们需要的长度。它是LONGLONG型的,就是说2的64次方。足够播放n年了 : ) 。
NOTE:如果你把它改的小,不论你怎么添加内存数据都不能持续的播放。directshow播放完这个长度的数据后就自动的停止了。
首先,初始化参数:
m_PlayBuf = new BYTE[32768*10];//我自己定义的数据缓冲
m_Buf Size = 0;//缓冲区未播放的数据大小,开始没数据,当然为0
m_llLength = 4000000000000;//这个大小足够播放了,4T的数据
hMutex   = CreateMutex(NULL,TRUE,"protect buf");//这是个HANDLE型的,用于播放和添加数据时,保护数据的完整性


接着就是Read函数了,它是自动调用的,而且是个work thread,参数pbBuffer是输出变量,就是要播放的数据,pdwBytesRead也是输出变量,表示读了的数据长度,其余是输入变量:
HRESULT Read(PBYTE pbBuffer,
DWORD dwBytesToRead,
BOOL bAlign,
LPDWORD pdwBytesRead)
{
   CAutoLock lck(&m_csLock);
   DWORD dwReadLength;


   dwReadLength = dwBytesToRead;//只有在最后的数据包改写该参数(因为不一定会符合32768的大小,我默认不修改)
   ///////////////////////////handle buf
   while (32768>m_Buf Size);//wait for add  new data


   WaitForSingleObject(hMutex, 1L); file://这一小段是关键
   CopyMemory((PVOID)pbBuffer, (PVOID)m_PlayBuf,dwReadLength);//从我们的缓冲中得到要播放的数据
   ReleaseMutex(hMutex);
   m_Buf Size -= dwReadLength;//未播放的数据大小减去刚刚播放的数据量dwReadLength
   CopyMemory((PVOID)m_PlayBuf, (PVOID)(m_PlayBuf+dwReadLength),m_Buf Size);//把未播放的数据移动到m_PlayBuf的开头,这样我们就不需要位置指针m_llPosition。这样有个好处,就是,m_llPosition实际上播放是会有一次从229376返回0,所以在播放位置的判断很麻烦,这就是为什么我弃用这个参数的原因。


   m_llPosition += dwReadLength;//这是memfile的代码,我没有去掉
   *pdwBytesRead = dwReadLength;
   return S_OK;
 }


最后就是我们怎么样才能更新我们的数据呢?在这里建立个线程比较合理。下面的函数是我自己添加到CmemStream类的。然后在主程序中建立线程来调用该函数。
LONGLONG AddBuf(PBYTE buf)
{
   if ((m_Buf Size +32768)>32768*10){//当添加的数据超过了我们的缓冲大小,则返回-1告诉调用程序,具体的处理由调用程序决定,是丢弃还是重发
    return -1;
   }
  
   WaitForSingleObject(hMutex, 1L);
   CopyMemory((PVOID)(m_PlayBuf+m_Buf Size),(PVOID)buf,32768);//把新的数据添加到我们自己的缓冲中
   ReleaseMutex(hMutex);


   m_Buf Size += 32768;//未播放的数据增加 了32768个字节
   return m_Buf Size;
  }


NOTE:上面多次有32768这个数字。这是它默认的数据大小,(修改可不容易,还不如自己写个新的source filter)。这就是我最开始提到的“延时问题”的问题的关键。因为一定需要32768字节的数据才能播放,所以32768就是我们延时的数据大小,你一定要等到数据增加到32768才能给出播放。如果32768对你的压缩数据来说,是一秒的数据,那么就延时一秒,如果是3秒的数据量,那么就延时3秒。这是这个类的限制。要想真正的实时,还是自己写source filter吧。我看过一个实时的产品,它好象有自己的compress 和uncompress filter等。
在网络的实时播放时,最重要的是数据的同步(得到新数据和播放之间),也就是Read()函数这个线程和AddBuf()函数这个线程之间的同步。如果AddBuf过快,数据就会丢失,过慢,则造成播放速度缓慢。我对多线程不是很有研究,所以我的播放事例只是简单的重发。当然你也可以丢包,不过,可以看到播放的效果就不行了。我也有代码同步,只是简单的Sleep()一段时间。是实际测试出来的(本地文件播放,只是演示。实际本地文件播放,只需重发包就行了,不会造成数据包的丢失)。也用与网络的播放,实测是1-2秒的时间延时。补充一点,数据包的丢失并不会造成播放的中断,只是画面上的停顿。


演示例子的说明
只是个简单的事例。很多的代码没有整理。
其中最主要的的是建立一个线程AddBufThreadProc。不断的添加数据。
DWORD  AddBufThreadProc(LPVOID p)
 {
 CFile f;
 PBYTE buf = new BYTE[32768];
 int   eof = 0;
 f.Open("e://R-161936-0600.mpg",CFile::modeRead);
   while(1)//add buf
   {
    eof = f.Read(buf,32768);//get new data,you can change it,example used socket
    if(eof!=32768)//if data finish
     break;
//    Sleep(175);//this way,if add too quick,maybe can lost data
    while(STREAM_SendBuf(buf)==-1);//this way,not lost data
   }
   f.Close();
   return 0;
  }


NOTE:
要注意的是,这个类本来是异步读文件的,受到天生的限制,用于实时播放是不太适合的(特别是当你的数据量相对32768来说,如果是5秒的话,是不能接受的。我的项目就是能够调节数据量,当最大时,延时小,只有1秒,数据量小时超过5秒)。如果用于实时的话,它只适合局域网或是宽带网。
当然,如果只是作为网络播放文件还是比较好的。如果网络速度低的话,还是传输MPEG-4 的好。默认是MPEG-1格式的,可以通过memfile的例子看到如何修改播放格式的,支持的挺多的:)。
有什么好的想法或是建议可以联系:afterain@263.net

Android实战——简单网络视频播放器 布局视图如下需要注意:此处使用接口来获取视频数据源,接口如下可以通过bejson.com这个网站来格式化Json数据,后续进行数据分析。完成数据源获取、创建适配器对象、设置适配器的代码编写@OverridesetTitle(“开眼视频”);// 数据源// 创建适配器对象// 设置适配器使用AS的GsonFormat插件自动生成bean类,此处代码不贴出。创建一个新的类,继承BaseAdapter。 阅读详情

相关推荐

【网络播放器】播放管理

播放管理 播放 先 stop 打开demuxer 可选 clear cache 创建cache管理 启动读取线程 读取线程应该与demuxer和cache协作 switch 到 加入频道 播放器状态切为 READY 加入频道会触发一个定时器 周期性 更新played time 如100ms 和 cached time 如500ms 暂停 idle ended stopped error 状态不触发 mediabuf 以 当前时间 记录 pausetime resume时 当前时间就是 pauseend

突围 393

播放器插件实现系列 —— DirectShow 之 SourceFilter

directshow 的文档比较详细,这里我们其实是要实现一个DirectShow 的 SourceFilter,在DirectShow提供的sdk包中,有实例代码(目录:Extras\DirectShow\Samples\C++\DirectShow\),我们的工程是拷贝Filters\PushSource然后做修改。 主要修改如下: 1、setup.cpp注册我们的filter 原来的P

luansxx的专栏 4623

网络音乐播放器完整功能实现示例

本文还有配套的精品资源,点击获取 简介:本示例展示了一个网络音乐播放器的功能实现,涉及音乐播放控制、网络数据获取、JSON数据解析、歌词信息同步以及用户界面设计等关键技术。重点讲解了如何使用Android的 MediaPlayer 和 ExoPlayer 库进行音频流控制、Volley库进行网络通信、Gson或Jackson库进行JSON处理,并...

weixin_42230607的博客 1695

DirectShow过滤器开发-读MP4视频文件过滤器

介绍“读MP4视频文件过滤器”的开发

h3974的博客 370

全功能自制网络媒体播放器项目实践

音频和视频编解码是将原始的音视频信号转换为数字文件的过程(编码),以及将数字文件还原为信号的过程(解码)。在AVI文件中,音频和视频数据通常使用不同的编解码器。对于视频编解码,常见的编解码器有DivX、XviD等,它们大多基于MPEG-4标准。这些编解码器通过压缩算法减少文件大小,同时尽量保持图像质量。音频方面,常见的编解码器包括PCM、MP3、AC3等。例如,MP3编解码器通过去除人耳无法察觉的声音频率信息来减少文件大小。在播放时,解码器的任务是将编码后的数据还原为可以播放的信号。

weixin_42143092的博客 1033

Directshow Capture Source Filter

虚拟视频采集设备,一个PushSource Filter,老外写的。没有摄像头也能采集图像数据,不过输出的图像是马赛克的。

directshow之filter开发---ASYNC例程解析

directshow的filter开发中,拉模式源filter开发例程的完整解析,详细解析各个关键点

bdmrg的专栏 1071

TypeScript领域建模实战:基于斯坦福本体论七步法构建健壮数据模型

在软件工程中,领域建模是连接业务需求与技术实现的关键桥梁,其核心在于对业务概念、属性及其关系的显式定义与规范。通过系统化的建模方法,开发者能够将模糊的领域知识转化为清晰、可扩展且类型安全的数据结构,从而在编译时捕获潜在错误,提升代码质量与可维护性。这一过程的技术价值在于实现了从业务逻辑到类型系统的无损映射,确保了设计的一致性。在实践中,结合TypeScript的静态类型检查与Zod的运行时验证,可以构建起从概念到代码再到数据库的三层一致性约束。本文以电商、博客等常见应用场景为例,深入解析如何运用源自斯坦福知

weixin_42551967的博客 383

DirectShow基础编程 最简单的源Filter的编写步骤

1.创建一个空的Dll工程,添加5个空文件分别名为:MyOutputPin.h、MySourceFilter.h、MyOutputPin.cpp、MySourceFilter.cpp和MySourceFilter.def。 2.声明两个类,一个是Filter的实现类,一个是输出Pin的实现类,由于是最简单的源Filter,因此Filter只有一个输出Pin。实现的功能是从本地磁盘读取三个图

馋嘴猪没胃口 5728

阿里系acw_sc__v3滑块验证码逆向分析与实战破解

本文深入解析阿里系acw_sc__v3滑块验证码的核心机制与逆向破解方法。通过分析加密参数生成、轨迹验证模块和动态加密策略,提供完整的自动化破解方案,包括设备指纹生成、缺口识别和轨迹加密等关键技术。文章还分享了常见问题的调试技巧,帮助开发者应对阿里系验证码的复杂防护体系。

wdx012345的博客 1829

从机械臂示教到厨房做饭:ACT模仿学习如何让机器人更“人性化”?

本文探讨了ACT(Action Chunking with Transformers)模仿学习技术如何让机器人更“人性化”,特别是在厨房等复杂场景中的应用。通过动作分块(Action Chunking)和时态融合(Temporal Ensemble)技术,机器人能够像人类一样记忆和执行复杂任务,如烹饪。文章还分析了ACT在家庭场景中的落地挑战及其在康复医疗、柔性制造等领域的跨领域应用潜力。

weixin_30613343的博客 255

QML网络音乐播放器

1_1_QML简介1_1_QML简介QML(Qt Meta-Language)是一种基于JavaScript的声明性语言,用于描述用户界面和应用程序的组件。QML是Qt框架的一部分,它使得开发人员可以更加轻松地创建现代化的、富交互性的用户界面。QML与C++紧密集成,使得开发人员可以在C++中使用QML组件,同时也可以从QML中调用C++代码,实现应用程序的逻辑和后端处理。QML的基本语法类似于JavaScript,但它更加简洁明了。

QT性能优化QT原理源码QT界面美化 878

手把手教你学Simulink--双足机器人分数阶PID控制仿真

分数阶PID(Fractional-order PID, FOPID)控制是一种先进的控制策略,它扩展了传统的整数阶PID控制器的概念。FOPID控制器允许积分和微分项的阶次不是严格的整数,而是可以是任意实数,这为系统提供了更多的设计自由度,并可能带来更好的性能。在双足机器人控制中,分数阶PID控制可以用于改善机器人的平衡控制、轨迹跟踪等任务的性能。下面我们将详细介绍如何使用Simulink进行基于分数阶PID控制方法的双足机器人仿真研究。

MHD0815的博客 879

QML网络视频播放器

QML简介QML简介QML(Qt Meta-Language)是Qt框架的一部分,是一种基于JavaScript的声明性语言,用于描述用户界面。QML与JavaScript一起使用,可以创建动态和交互式的用户界面。QML是Qt Quick的编程语言,Qt Quick是一个用于快速开发跨平台应用程序的库。为什么使用QML?QML的主要优点是它提供了一种简单而直观的方式来描述用户界面,使得界面开发更加快速和高效。QML的声明性特性使得开发者可以更加关注于要实现的用户界面,而不是如何构建界面。

QT性能优化QT原理源码QT界面美化 1421

Unity动态创建Avatar骨骼映射

Unity Avatar骨骼映射动态创建,适配Unity通用动画,无需经过第三方建模软件,可运行时创建

Nbin_Newby的博客 1万+

EtherCAT报文-BRD(广播读)抓包分析

EtherCAT报文之BRD(广播读)报文Wireshark抓包分析。

kevin1499的博客 1212

android网络音乐播放器

** 网络音乐播放器 ** 转载请指明博客网址 作者:WangYouHu我的主页网址 链接:https://www.jianshu.com/p/855659f266ae 著作权归作者所有,任何形式的转载都请联系本人获得授权并注明出处。 相信大家不想再去了解那些本地音乐的了 其实网络获取音乐也没有那么复杂 你只需要有一个自己uri所谓的网址 但必须只有音乐文件 没有其他的元素 这里我为了方便自己搭建...

王幼虎 4839

从零实现深度学习框架——理解正则化(一)

本文介绍解决过拟合与欠拟合的方法——正则化,主要介绍L1和L2正则化。

日积月累,天道酬勤 3394

基于JSP技术的网络视频播放器

本文介绍了一个基于JSP技术的网络视频播放器的设计和实现。随着社会的发展,信息科学化管理的重要性日益凸显,网络视频播放器作为一种信息管理工具,其设计和实现具有重要的实际意义。本文首先分析了网络视频播放器的开发背景和现状,然后详细论述了系统的设计目标、需求分析、设计方案以及具体的实现过程。系统采用了B/S结构,后台数据库使用了MySQL,前端页面设计采用了JSP技术。通过对系统进行测试,验证了其功能的完整性和稳定性。本文通过详细的分析和设计,成功实现了一个基于JSP技术的网络视频播放器。

a632341031的博客 2004

24年电赛H题 | 想要小车走直线,正在调角度环,但不知道怎么把角度偏航角偏差转化成电机速度输出?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1313

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

python+vue网络视频播放器/视频播放器软件/在线视频播放器/网络播放器/播放器系统/高清网络播放器/视频流媒体播放器

21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存储达到准确、快速、完善,并能提高工作管理效率,促进其发展。

QQ511008285的博客 947

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

我的网络播放器

 想听自己想听的歌吗?想看自己想看的电影吗?---想;但又不想耗费自己更多的硬盘空间。CPU资源. 真想拥有自己的一个简单功能强大的 但又不需要付钱的 播放器等。本人推出的网络音频播放器。网络视频播放器.将满足这些朋友的要求。具体发布时间。敬请关注后续发布..............................此播放器 支持播放本地和网络上的音频资源文件如大家在使用此软

m_chenzhi的专栏 362

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Android Studio实现网络视频播放器

本次项目实现了一个简单的网络视频播放器,调用的是高度自定义的视频框架jiaozivideoplayer。通过gson解析网络视频的api,获取每个视频的url、点赞量和评论数。获取到数据源后,我们再创建适配器,给列表设置下适配器,加载网络数据,从而进行视频播放。HttpUtils是获取Http请求的工具类,MainActivity是主活动,在其中让子线程发送消息提醒适配器更新数据

振华OPPO的博客世界 7094

ESP32网络音频播放器软硬件框图

一、前言 今天这篇博文记录一下有小伙伴问我如何通过ESP32实现一个网络音频流播放器,故提供了一下对应的软硬件框图,以此作为记录。对于软件上具体如何从零开始实现,请阅读我的其他对应博文。 二、框图 ...

coderma的博客 3007
上一篇: 关于push和pull模式的说明
下一篇: directshow的中文资料之播放影片
capboy
博客等级 码龄26年 15粉丝 34原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值