zoukankan      html  css  js  c++  java
  • EasyPlayerPro windows播放器之多窗口播放音量控制方法

    EasyPlayerPro-win基础版本的音频播放为单一通道播放,即同一时间仅允许一个通道播放声音,现应客户需求,在基础版本上实现独立的音频播放,即每个通道可同时播放视频和音频;

    EasyPlayerPro windows播放器

    设计思路

    将音频播放类DirectSoundPlayer移到每个播放通道中, 取消之前的音频通道关系判断; 音量控制类保持不变;

    DirectSoundPlayer 实现

    1. 打开音频播放设备 Open(WAVEFORMATEX *pWaveFormatEx);
    2. 调用开始播放;
    3. 将音频数据写入队列;
    4. 播放线程从队列中读取数据开始播放;
    5. 调用停止播放;
    6. 关闭音频播放设备;

    注: 在没有声音数据时,需填充为静音数据. 否则会一直播放最后一帧的音频;

    播放数据填充代码如下:  
    
    while (1)
    {
        if (pDirectSoundObj->flag == 0x03)          break;
    
    
        if ( (res >= WAIT_OBJECT_0) && (res < WAIT_OBJECT_0+DIRECT_SOUND_BUFFER_NUM) )
        {
            pDirectSoundObj->audioFrameNum = BUFQUE_GetFrameNum(pDirectSoundObj->buffQueue, consumerHandle, BUFFER_TYPE_AUDIO);
    
            unsigned char *pbuf = NULL, *pbuf2=NULL;
            DWORD buflen = 0, buflen2=0;
    
            HRESULT hr = pDirectSoundObj->pDirectSoundBuffer8->Lock(offset, pDirectSoundObj->packetSize, (LPVOID*)&pbuf, &buflen, (LPVOID*)&pbuf2, &buflen2, 0);
            if (DSERR_BUFFERLOST == hr)
            {
                pDirectSoundObj->pDirectSoundBuffer8->Restore();
                hr = pDirectSoundObj->pDirectSoundBuffer8->Lock(offset, pDirectSoundObj->packetSize, (LPVOID*)&pbuf, &buflen, (LPVOID*)&pbuf2, &buflen2, 0);
            }
    
    
            if (buflen > 0)
            {
                int ret = BUFQUE_GetData(pDirectSoundObj->buffQueue, consumerHandle, NULL, &bufferType, NULL, NULL, &sourceBuff.bufpos, sourceBuff.pbuf, 0x01);
                if ( (ret == 0x00) && (buflen == sourceBuff.bufpos) )
                {
                    memcpy(pbuf, sourceBuff.pbuf, sourceBuff.bufpos);
    
                    if (buflen2 > 0)
                    {
                        ret = BUFQUE_GetData(pDirectSoundObj->buffQueue, consumerHandle, NULL, &bufferType, NULL, NULL, &sourceBuff.bufpos, sourceBuff.pbuf, 0x01);
                        if (ret == 0x00 && buflen2 == sourceBuff.bufpos)
                        {
                            memcpy(pbuf2, sourceBuff.pbuf, sourceBuff.bufpos);
                        }
                    }
                }
                else
                {
                    memset(pbuf, 0x00, buflen);     //填充为静音
                }
    
                pDirectSoundObj->pDirectSoundBuffer8->Unlock(pbuf, buflen, pbuf2, buflen2);
            }
    
            offset += (buflen+buflen2);
            if (offset >= pDirectSoundObj->directSoundBufferDesc.dwBufferBytes) offset = 0;
        }
    
    
    
        ....
    }
    

    关于EasyPlayerPro

    EasyPlayerPro是一款全功能的流媒体播放器,支持RTSP、RTMP、HTTP、HLS、UDP、RTP、File等多种流媒体协议播放、支持本地文件播放,支持本地抓拍、本地录像、播放旋转、多屏播放、倍数播放等多种功能特性,核心基于ffmpeg,稳定、高效、可靠、可控,支持Windows、Android、iOS三个平台,目前在多家教育、安防、行业型公司,都得到的应用,广受好评!

    EasyPlayerPro:https://github.com/EasyDSS/EasyPlayerPro

    点击链接加入群【EasyPlayer & EasyPlayerPro】:544917793

    技术支持

    获取更多信息

    EasyDarwin开源流媒体服务器:www.EasyDarwin.org

    EasyDSS商用流媒体解决方案:www.EasyDSS.com

    EasyNVR无插件直播方案:www.EasyNVR.com

    Copyright © EasyDarwin Team 2012-2017

    EasyDarwin

  • 相关阅读:
    Spring事务内方法调用自身事务 增强的三种方式
    SpringBoot优化内嵌的Tomcat
    Tomcat 8.0的并发优化
    Swift搭建本地http服务器,实现外部视频即时播放
    更新ruby:Error running 'requirements_osx_brew_update_system ruby-2.4.1报错解决
    iOS关于沙盒文件拷贝manager.copyItem的一个坑
    Swift udp实现根据端口号监听广播数据(利用GCDAsyncUdpSocket实现)
    iOS刻度尺换算之1mm等于多少像素理解
    Swift下的基于UIView的位置属性扩展
    iOS Main Thread Checker: UI API called on a background thread的解释
  • 原文地址:https://www.cnblogs.com/babosa/p/8206956.html
Copyright © 2011-2022 走看看