mms流媒体服务器搭建(包含预览即本地播放)

实现功能说明:
实现服务端与客户端视频文件实时播放功能即直播功能(注:服务端和客户端有延迟),服务端截图如下:
这里写图片描述
客户端可以使用vlc播放器通过如下地址播放:mms://127.0.0.1:8041(注:127.0.0.1是本机回环Ip,至于什么是回环IP,自己百度)
其他说明:
1.此流媒体开发是基于windows media encoder SDK开发,而这个sdk又需要依赖windows media encode中的库文件,因此,开发之前,先安装这两个软件,开发过程中只要包含windows media encoder SDK即可,下载地址为(window7亲测可用):http://download.csdn.net/download/zaokang5603/10028002
2.目前上面只支持windows的媒体文件,如果想要支持avi,rmvb视频各种,可以下载个编解码器,例如FinalCodecs,安装即可,无需额外配置
3.如果想要两边支持实时播放,且服务器这边可以有音频输出,那么可以在开始编码之后,可以使用wmPlayer控件,播放此文件,和预览的道理是一样的
4.以下代码是基于vs2013开发,工程下载地址为:http://download.csdn.net/download/zaokang5603/10118016
5.本人也是初次开发,哪里有问题,留言说明,莫喷!
代码片段如下:
#define RELEASE_PTR {\
if (pSrcGrpColl)\
{\
pSrcGrpColl->Release(); \
pSrcGrpColl = NULL; }\
if (pSrcGrp)\
{\
pSrcGrp->Release(); \
pSrcGrp = NULL; \
}\
if (pAudSrc)\
{\
pAudSrc->Release(); \
pAudSrc = NULL; \
}\
if (pVidSrc)\
{\
pVidSrc->Release(); \
pVidSrc = NULL; \
}\
if (pProColl)\
{\
pProColl->Release(); \
pProColl = NULL; \
}\
if (pPro)\
{\
pPro->Release(); \
pPro = NULL; \
}\
if (pPro2)\
{\
pPro2->Release(); \
pPro2 = NULL; \
}\
if (pBrdCst)\
{\
pBrdCst->Release(); \
pBrdCst = NULL; \
}\
if (pPreviewColl)\
{\
pPreviewColl->Release(); \
pPreviewColl = NULL; \
}\
}
void CmsdntestDlg::OnBnClickedButton1()//开启流媒体按钮
{
// TODO: 在此添加控件通知处理程序代码

CComBSTR serverFilePath;
{
    CFileDialog dlgFile(TRUE);
    if (dlgFile.DoModal() == IDOK)
    {
        CString file = dlgFile.GetPathName();
        serverFilePath = file.AllocSysString();
        //m_path = file.AllocSysString();
        //m_serverFilePath = WideCharToUTF8(bstr);
    }
}
CoUninitialize();//必须先要添加这一坨,可能dlgFile析构没有CoUninitialize造成流媒体广播一段时间就挂掉了
if (!Initencoder(serverFilePath))//搭建mms流媒体服务器
{
    AfxMessageBox("encoding file failed!");
    GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
    return;
}
SysFreeString(serverFilePath);
GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
}
    BOOL CmsdntestDlg::Initencoder(CComBSTR &filePath)
    {
        IWMEncSourceGroupCollection* pSrcGrpColl = NULL;
        IWMEncSourceGroup* pSrcGrp = NULL;
        IWMEncSource* pAudSrc = NULL;
        IWMEncSource* pVidSrc = NULL;
        IWMEncProfileCollection* pProColl = NULL;
        IWMEncProfile* pPro = NULL;
        IWMEncProfile2* pPro2 = NULL;
        IWMEncBroadcast* pBrdCst = NULL;
        IWMEncDataViewCollection* pPreviewColl = NULL;


//IWMEncProfile* pPro = NULL;


// Initialize the COM library and retrieve a pointer
// to an IWMEncoder interface.
if (FAILED(CoInitialize(NULL)))
{

    return FALSE;
}
if (!m_pEncoder)
{
    if (FAILED(CoCreateInstance(CLSID_WMEncoder,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_IWMEncoder,
        (void**)&m_pEncoder)))
    {
        return FALSE;
    }
}



// Retrieve a pointer to an IWMEncSourceGroupCollection
// interface.

if (FAILED(m_pEncoder->get_SourceGroupCollection(&pSrcGrpColl)))//获得解码器集合
{
    return FALSE;
}

// Add a new source group to the collection.

if (FAILED(pSrcGrpColl->Add(CComBSTR("SG_1"), &pSrcGrp)))//获得解码器组
{
    RELEASE_PTR;
    return FALSE;
}


// Add an audio and avideo source to the source group.

if (FAILED(pSrcGrp->AddSource(WMENC_AUDIO, &pAudSrc)))//添加音频资源
{
    RELEASE_PTR;
    return FALSE;
}
if (FAILED(pSrcGrp->AddSource(WMENC_VIDEO, &pVidSrc)))//添加视频资源
{
    RELEASE_PTR;
    return FALSE;
}
// Specify an .avi source file and a .wmv output file.
if (FAILED(pAudSrc->SetInput(filePath)))//获得文件音频源
{
    RELEASE_PTR;
    return FALSE;
}

if (FAILED(pVidSrc->SetInput(filePath)))//获得文件视频源
{
    RELEASE_PTR;
    return FALSE;
}


// Loop through the profile collection and retrieve a specific
// profile.
if (FAILED(m_pEncoder->get_ProfileCollection(&pProColl)))//获得配置集合
{
    RELEASE_PTR;
    return FALSE;
}

if (!creatprofile(&pPro2))//创建配置文件
{
    AfxMessageBox("creatProfile failed!");
    RELEASE_PTR;
    return FALSE;
}
if (FAILED(pPro2->QueryInterface(IID_IWMEncProfile, (void**)&pPro)))
{
    RELEASE_PTR;
    return FALSE;
}

if (FAILED(pSrcGrp->put_Profile(CComVariant(pPro))))//把配置文件配置给资源组,即解码器
{
    RELEASE_PTR;
    return FALSE;
}

if (!m_pPreview)
{
    if (FAILED(CoCreateInstance(CLSID_WMEncPreview,
        NULL,
        CLSCTX_INPROC_SERVER,
        IID_IWMEncDataView,
        (void**)&m_pPreview)))//创建预览对象
    {
        RELEASE_PTR;
        return FALSE;
    }
}



// Retrieve the preview collection.

if (FAILED(pVidSrc->get_PreviewCollection(&pPreviewColl)))//获取预览集合
{
    RELEASE_PTR;
    return FALSE;
}


// Add the preview object to the data view collection. If you set the
// cookie to -1, the encoding process automatically generates a unique
// cookie.


if (FAILED(pPreviewColl->Add(m_pPreview, &m_lCookie)))//把预览添加进预览集合
{
    RELEASE_PTR;
    return FALSE;
}

if (FAILED(m_pEncoder->get_Broadcast(&pBrdCst)))//广播
{
    RELEASE_PTR;
    return FALSE;
}
;

// Select the 5th profile from the collection and set it into the source group.
if (FAILED(pBrdCst->put_PortNumber(WMENC_PROTOCOL_HTTP, 8401)))//广播端口8401,即客户端通过 mms://127.0.0.1:8041地址即可观看直播,注:127.0.0.1是用当前服务器ip,非此ip
{
    RELEASE_PTR;
    return FALSE;
}


if (FAILED(m_pEncoder->PrepareToEncode(VARIANT_TRUE)))//准备开始编解码
{
    RELEASE_PTR;
    return FALSE;
}

HWND hWnd = GetDlgItem(IDC_STATIC)->GetSafeHwnd();
if (FAILED(m_pPreview->SetViewSetting((DWORD)m_lCookie,
    sizeof(hWnd),
    (BYTE*)&hWnd)))//获得picture control 句柄
{
    RELEASE_PTR;
    return FALSE;
}



if (FAILED(m_pEncoder->Start()))//开始编解码
{
    RELEASE_PTR;
    return FALSE;
}

if (FAILED(m_pPreview->Start(m_lCookie)))//开始预览播放
{
    RELEASE_PTR;
    return FALSE;
}
//IWMEncProfileCollection* pProColl = NULL;

RELEASE_PTR;

return TRUE;
}

BOOL CmsdntestDlg::creatprofile(IWMEncProfile2** pPro2)
{

IWMEncAudienceObj* pAudnc = NULL;
BOOL isOk = TRUE;

//以下各个参数代表什么,可以查看windows media encoder SDk帮助文档,有详细介绍
// Initialize the COM library and retrieve a pointer to an IWMEncProfile2 interface.
if (FAILED(CoCreateInstance(CLSID_WMEncProfile2,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_IWMEncProfile2,
    (void**)pPro2)))
{
    return FALSE;

}

// Verify profile settings immediately as they are set.
if (FAILED((*pPro2)->put_ValidateMode(VARIANT_TRUE)))
{

    return FALSE;
}

// Provide a name and description.
if (FAILED((*pPro2)->put_ProfileName(CComBSTR("Sample MBR Profile"))))
{

    return FALSE;
}
if (FAILED((*pPro2)->put_ProfileDescription(CComBSTR("A video profile with three audiences"))))
{

    return FALSE;
}

// specifies the type of content streams that the current profile supports
if (FAILED((*pPro2)->put_ContentType(17)))//每个数字代表不一样文件格式,具体查看Wmencoder SDk帮助文档
{

    return FALSE;
}

// Specify constant bit rate (CBR) mode.
if (FAILED((*pPro2)->put_VBRMode(WMENC_VIDEO, 0, WMENC_PVM_UNCONSTRAINED)))
{

    return FALSE;
}

// Add audiences for 200, 400, and 600 Kbps.
if (FAILED((*pPro2)->AddAudience(5000000, &pAudnc)))
{

    return FALSE;
}
if (FAILED(pAudnc->put_VideoCodec(0, 3)))
{
    pAudnc->Release();
    pAudnc = NULL;
    return FALSE;
}

// Make the video output size match the input size by setting height and width to 0.
if (FAILED(pAudnc->put_VideoHeight(0, 0)))
{
    pAudnc->Release();
    pAudnc = NULL;
    return FALSE;
}
if (FAILED(pAudnc->put_VideoWidth(0, 0)))
{
    pAudnc->Release();
    pAudnc = NULL;
    return FALSE;
}

// Change the buffer size to 5 seconds. By default, the end user's default setting is used.
if (FAILED(pAudnc->put_VideoBufferSize(0, 5000)))
{
    pAudnc->Release();
    pAudnc = NULL;
    return FALSE;
}

//specifies the video codec quality.

if (FAILED((*pPro2)->get_Audience(0, &pAudnc)))
{
    pAudnc->Release();
    pAudnc = NULL;
    return FALSE;
}

if (FAILED(pAudnc->put_VideoCompressionQuality(0, 80)))//视频压缩比例
{
    pAudnc->Release();
    pAudnc = NULL;
    return FALSE;
}

// Change the video image sharpness for the first audience only.
if (FAILED(pAudnc->put_VideoImageSharpness(0, 70)))
{
    pAudnc->Release();
    pAudnc = NULL;
    return FALSE;
}

// Validate the settings to make sure the profile has no errors.
if (FAILED((*pPro2)->Validate()))
{
    pAudnc->Release();
    pAudnc = NULL;
    return FALSE;
    }

    // Save the profile to a .prx file.
    /*if (FAILED((*pPro2)->SaveToFile(CComBSTR("D:\\test.prx"))))
    {
    printf("profile error:SaveToFile \n");
    }*/

    // Release pointers.
    if (pAudnc)
    {
        pAudnc->Release();
        pAudnc = NULL;
    }

    return TRUE;


    }


void CmsdntestDlg::OnBnClickedButton2()//关闭流媒体按钮
{
    // TODO:  在此添加控件通知处理程序代码
    if (m_pPreview)
    {
        m_pPreview->Stop(m_lCookie);
        m_pPreview->Release();
        m_pPreview = NULL;
    }
    if (m_pEncoder)
    {
        m_pEncoder->Stop();
        m_pEncoder->Release();
        m_pEncoder = NULL;
    }
    GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
    CoUninitialize();
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容由流媒体协议等基本知识,视频媒体基本知识,流媒体服务器搭建实战,流媒体工具使用实战等内容组成。由本人“天地会珠海分舵”(http://blog.csdn.net/zhubaitian)耗时一个月整理而成,现分享给大家。 章节内容分布如下: 第1章Streaming 协议和服务器概览学习摘录 7 1.1 Protocol support 8 1.2 Media Container format support 12 第2章Streaming 协议学习摘录 15 2.1 MMS协议简介 15 2.2 RTP相关协议简介 15 2.2.1 RTP与RTCP协议简介 15 2.2.2 RTSP协议简介 16 2.2.3 流传输过程 17 2.3 RTMP vs RTMFP 18 2.3.1 RTMP协议简介 18 2.3.3 RTMFP 简介 19 2.3.4 RTMP VS RTMFP 20 2.4 MPEG-TS 20 2.4.1 MPEG2-TS与MPEG2-PS的区别 20 2.4.2 PES/ES/TS简介 20 2.5 Smooth Streaming 21 2.5 HLS简介 24 2.6 MPEG-DASH 26 2.6.1 简介 26 2.6.2 Dash播放器列表 28 2.6.3 MPD格式 30 2.6.5 MPD在线检查器 31 2.6.5 MPD 格式理解个人小结 31 2.6.6 PMD格式的多样性 32 2.6.7 MPD 支持的Profiles 44 2.6.8 DASH传输协议支持 44 2.7 HLS VS MPEG-DASH 45 2.8 Real Data Transport Protocol 45 2.9 webM 45 第3章 视频容器格式学习摘录 47 3.1 视频容器VS 视频编码 47 3.2 3GP容器 48 3.2 AVI容器(.avi) 49 3.3 WMV vs ASF 容器(.wmv/.asf) 49 3.3.1 ASF高级串流格式简介以及和WMA/WMV的区别 49 3.3.2 ASF和WMA/WMV的区别官方解析 50 3.4 QuickTime容器(.mov) 50 3.5 Ogg vs Ogm容器(.ogg) 51 3.5.1 Ogg容器格式 51 3.5.2 Ogm 51 3.5.3 Ogg vs Ogm 52 3.6 Matroska容器(.mkv|.mka|.mks) 52 3.7 MP4容器 53 3.7.1 简介 53 3.7.2 MP4格式详解 53 3.8 MPEGE TS容器 61 3.9 FLV容器 62 3.10 ABS – Adaptive Bitrate Streaming 自适应串流容器 62 3.11 码率 63 3.12 流媒体的3种格式 63 3.12.1 压缩媒体文件格式 63 3.12.2 流文件格式 64 3.12.3 流媒体发布格式 64 第4章 视频编码格式学习摘录 66 4.1视频编码格式简介 66 4.2主流视频编码格式比较 67 4.2.1 MPEG编码格式 67 4.2.2 DivX/XviD编码格式 68 4.2.3 H.264/X264编码格式 69 4.2.4 WMA-HD/VC-1编码格式 71 4.2.5 各主流编码格式比较 72 4.3 视频解码 73 第5章ffmpeg学习摘录 74 5.1 简介 74 5.2 功能 74 5.3 支持的格式和编码 75 5.4 支持的流媒体协议 76 5.5 ffmpeg视频解码架构示例简略 76 5.5.1 解复用(Demux) 77 5.5.2 解码 (Decode) 78 5.5.3 Ffmpeg中解码流程对应的API函数 78 第6章GStreamer学习摘录 80 6.1 GStreamer简介 80 6.2 GStreamer编写MP3播放器实例 80 6.2.1 初始化GStreamer 80 6.2.2 创建GStreamer管道元件 81 6.2.3 创建元件三元组之GStreamer数据源 81 6.2.4 创建元件三元组之解码器 (即GStreamer过滤器) 插件 81 6.2.5 创建元件三元组之GStreamer接收器 81 6.2.6 链接GStreamer元件三元组到管道 – 播放 82 6.2.7 启动GStreamer管道数据处理流程 82 6.2.8 MP3命令行播放器源代码完整实例 82 第7章 ffmpeg VS GStreamer比较学习摘录 85 7.1 Pipeline设计模式简介 85 7.2 ffmpeg vs GStreamer 86 7.2.1 网上解析翻译 86 7.2.1 FFmpeg和GStreamer异同小结 87 第8章 流媒体服务器搭建摘录 88 8.1 VLC 88 8.1.1 VLC编码和容器兼容性 88 8.1.1 VLC 配置VOD点播 88 8.1.2 VLC 配置组播服务器 90 8.2 Wowza Streaming Engine 91 8.2.1 简介及安装 91 8.2.2 MPEG-DASH 支持 92 8.2.3 如何使用VLC作为直播源 95 8.2.4 点播VOD配置 112 8.3 Nex Gen Media Server (NGMS) 114 8.3.1 Introduction 114 8.3.2 Feature List 115 8.3.3 Practice in Action 116 8.4 IIS Smooth Streaming(IIS Media Service) 117 8.4.1 Getting Started with IIS Smooth Streaming 117 8.4.2 Use VLC to play the Smooth Stream 128 8.4.3 创建Smooth Stream 文件 129 8.4.4 提供DASH服务时IIS的关键设置 129 8.4.5 Dash on IIS步骤 130 第9章 相关工具学习摘录 137 9.1 Bento4 MP4工具包 137 9.1.1 Introduction 137 9.1.2 所包含的工具简介 138 9.1.3 MPEG DASH Adaptive Streaming 139 9.1.4 Serving DASH Streams 147 9.2 MP4Box 149 9.2.1 简介 149 9.2.2 对DASH的支持命令帮助 150 9.2.3 MP4Box: fragmentation, segmentation, splitting and interleaving 153 9.2.4 把MP4转换成TS 155 9.2.5生成不同profile的MPD 155 9.2.6指定每个Representation的bandwidth 156 9.2.7生成多个period的MPD 156 9.2.8生成多个Representation的MPD 156 9.2.9 生成多个Segment的MPD 156 9.2.10 生成(Subsegment) SegmentBase拥有 indexRangeExact 为true的MPD 157 9.2.11 生成多个AdaptionSet的MPD 158 9.2.12 模拟live直播 158 第10章 流媒体服务器搭建指导 159 10.1 所需搭建服务器Matrix 159 第11章 附录 163 11.1 Wowza支持格式 163 11.2 ISO Base Media File Format (IBMFF) 163 11.3 DASH所支持Profile分类 164

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值