【精选】C/C++ 视频播放器开发 您所在的位置:网站首页 视频播放器app开发教程 【精选】C/C++ 视频播放器开发

【精选】C/C++ 视频播放器开发

2023-11-21 10:50| 来源: 网络整理| 查看: 265

文章目录 前言一、下载VLC库二、VLC使用介绍三、成品演示四、开始开发UI设计封装VLC库UI与CVLC类结合初始化播放按钮暂停按钮进度条响应函数音量响应函数播放速率响应事件定时器响应事件

前言

如果对学习C/C++有兴趣,可以看看这篇文章哦:C/C++教程

C/C++开发方向之一就是音视频,本文以当前流行的VLC开源库为基础,开发一个视频播放器。

在这里插入图片描述

一、下载VLC库

最新库的下载地址点这里 在这里插入图片描述 可选择自己需要的版本,我下载的为win64 在这里插入图片描述 下载压缩包,解压,将图中两个dll和一个文件夹复制到项目文件中 在这里插入图片描述 进入sdk库 在这里插入图片描述 将这两个文件夹拷贝到自己的项目文件中去 在这里插入图片描述 此时项目文件如下: 在这里插入图片描述 回到项目中,添加include和lib文件夹到项目配置中 在这里插入图片描述 添加如下代码即可正常使用 在这里插入图片描述

typedef long long ssize_t; //目前需要定义,否则编译失败 #include //添加头文件 #pragma comment(lib,"libvlc.lib") //添加libvlc.lib库 #pragma comment(lib,"libvlccore.lib") //添加libvlccore.lib库 二、VLC使用介绍 创建vlc实例:libvlc_new为要播放的视频创建媒体实例:libvlc_media_new_path为媒体实例创建一个播放对象:libvlc_media_player_new_from_media对播放对象进行一系列操作,比如播放、暂停、停止,调整音量等释放前三步创建的实例:libvlc_media_player_release,libvlc_media_release,libvlc_release

代码演示:

typedef long long ssize_t; //目前需要定义,否则编译失败 #include //添加头文件 #include #include #pragma comment(lib,"libvlc.lib") //添加libvlc.lib库 #pragma comment(lib,"libvlccore.lib") //添加libvlccore.lib库 std::string toUTF8(std::wstring data) { int len=WideCharToMultiByte(CP_UTF8,0,data.data(),-1,0,0,0,0); std::string s; s.resize(len+1); WideCharToMultiByte(CP_UTF8,0,data.data(),-1,(LPSTR)s.data(),len+1, 0, 0); return s; } int main() { libvlc_instance_t* vlc_ins = libvlc_new(0,NULL); //创建vlc实例 std::string path = toUTF8(L"测试视频.mp4"); //转码为UTF-8 libvlc_media_t* media = libvlc_media_new_path(vlc_ins,path.data());//为视频创建播放对象 libvlc_media_player_t * player=libvlc_media_player_new_from_media(media); //创建播放对象 do { int ret=libvlc_media_player_play(player); //进行播放 if (ret == -1) break; Sleep(1000); //休眠1秒,给时间缓存,否则数据可能获取失败 libvlc_time_t tm = libvlc_media_player_get_length(player); //获得视频长度 printf("%02lld:%02lld:%02lld\n", tm / 3600000, tm / 60000 % 60, tm /1000 % 60); int width=libvlc_video_get_width(player); //获取视频宽度 int hight=libvlc_video_get_height(player); //获取视频高度 printf("width=%d height=%d\n",width,hight); getchar(); //等待一次按键 libvlc_media_player_pause(player); //暂停视频播放 getchar(); libvlc_media_player_play(player);//视频继续播放 getchar(); libvlc_media_player_stop(player); //停止视频播放 getchar(); } while (0); libvlc_media_player_release(player); //释放播放实例 libvlc_media_release(media); //释放媒体实例 libvlc_release(vlc_ins); //释放VLC实例 }

几点说明:

vlc库默认为utf-8编码,如果文件名中有中文,必须先转化为UTF-8编码do{}while(0)结构可能觉得奇怪,这是为了中途出错,直接跳出循环,释放实例获取的视频长度以微秒作为单位名字叫测试视频.mp4放在了当前项目目录下,如果在其它目录,需要指定完整路径 在这里插入图片描述

运行结果: 在这里插入图片描述

视频正常播放

三、成品演示

在这里插入图片描述 基本功能都实现了,可能存在一定的小bug,可自己稍微修复一下

项目下载可点击这里

四、开始开发

功能需求:播放,暂停/继续,停止,速率,进度显示,跳转位置,地址输入等功能

主要模块:封装VLC库函数为一个简单易用的类

界面:采用MFC的对话框项目 在这里插入图片描述

UI设计

选择MFC项目在这里插入图片描述 取名 在这里插入图片描述 选择项目属性:

注意,除了应用程序类型必须选基于对话框,其它可随意 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 然后点击确定,生成项目

在这里插入图片描述 拖动控件,设计UI,结果如下: 在这里插入图片描述

封装VLC库

CVlc.h

#pragma once #include typedef long long ssize_t; #include struct MediaSize { int width; int hight; MediaSize(int _width,int _hight) { width = _width; hight = _hight; } }; class CVlc { private: libvlc_instance_t* m_instance; libvlc_media_t* m_media; libvlc_media_player_t* m_player; HWND m_hWnd; private: //转换编码为utf-8 std::string ToUTF8(const std::wstring& str); public: CVlc(); ~CVlc(); //加载媒体 bool LoadMedia(const std::wstring &path); //设置播放窗口 void SetHWnd(HWND hWnd); //播放 bool Play(); //暂停 bool Pause(); //停止 bool Stop(); //获取播放进度 float GetPosition(); //设置播放进度 void SetPosition(float pos); //获取音量 int GetVolume(); //设置音量 void SetVolume(int volume); //获取媒体时长 int GetLenth(); //设置播放速率 bool SetRate(float rate); //获取媒体宽高 MediaSize GetMediaInfo(); };

CVlc.cpp

#include "pch.h" #include "CVlc.h" std::string CVlc::ToUTF8(const std::wstring& str) { int len = WideCharToMultiByte(CP_UTF8, 0, str.data(), -1, 0, 0, 0, 0); std::string s; s.resize(len + 1); WideCharToMultiByte(CP_UTF8, 0, str.data(), -1, (LPSTR)s.data(), len + 1, 0, 0); return s; } CVlc::CVlc() { m_instance = libvlc_new(0, NULL); m_media = NULL; m_player = NULL; m_hWnd = NULL; } CVlc::~CVlc() { if (m_player != NULL) { libvlc_media_player_release(m_player); m_player = NULL; } if (m_media != NULL) { libvlc_media_release(m_media); m_media = NULL; } if (m_instance != NULL) { libvlc_release(m_instance); m_instance = NULL; } } bool CVlc::LoadMedia(const std::wstring& path) { if (m_instance == NULL) return false; std::string s=ToUTF8(path); if (m_media != NULL) { libvlc_media_release(m_media); m_media = NULL; } m_media=libvlc_media_new_location(m_instance,s.data()); if (m_media == NULL) return false; if (m_player != NULL) { libvlc_media_player_release(m_player); m_player = NULL; } m_player=libvlc_media_player_new_from_media(m_media); if (m_player == NULL) return false; return true; } void CVlc::SetHWnd(HWND hWnd) { m_hWnd = hWnd; } bool CVlc::Play() { if (m_player == NULL) return false; if (m_hWnd != NULL) { libvlc_media_player_set_hwnd(m_player, m_hWnd); } int ret = libvlc_media_player_play(m_player); return ret == 0; } bool CVlc::Pause() { if (m_player == NULL) return false; libvlc_media_player_pause(m_player); return true; } bool CVlc::Stop() { if (m_player == NULL) return false; libvlc_media_player_stop(m_player); return true; } float CVlc::GetPosition() { if (m_player == NULL) return false; return libvlc_media_player_get_position(m_player); } void CVlc::SetPosition(float pos) { if (m_player == NULL) return; libvlc_media_player_set_position(m_player,pos); } int CVlc::GetVolume() { if (m_player == NULL) return 0; return libvlc_audio_get_volume(m_player); } void CVlc::SetVolume(int volume) { if (m_player == NULL) return; libvlc_audio_set_volume(m_player,volume); } int CVlc::GetLenth() { if (m_player == NULL) return -1; libvlc_time_t tm=libvlc_media_player_get_length(m_player); if (tm == -1) return -1; return tm/1000; } bool CVlc::SetRate(float rate) { if (m_player == NULL) return false; return 0==libvlc_media_player_set_rate(m_player,rate); } MediaSize CVlc::GetMediaInfo() { if (m_player == NULL) return MediaSize(0,0); return MediaSize( libvlc_video_get_width(m_player), libvlc_video_get_height(m_player) ); } UI与CVLC类结合

全局变量: 在这里插入图片描述

初始化 BOOL CVideoPlayerDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 //初始化控件 SetDlgItemText(IDC_ST_TIME, _T("--/--")); m_volume.SetRange(0, 100); m_volume.SetTicFreq(10); SetDlgItemText(IDC_ST_VOLUME, _T("100%")); m_vlc.SetHWnd(m_video.GetSafeHwnd()); //设置播放窗口 m_rate.SetCurSel(0); //初始化倍率为1 return TRUE; // 除非将焦点设置到控件,否则返回 TRUE } 播放按钮 void CVideoPlayerDlg::OnBnClickedPlay() { if (m_isPlay) { //如果正在播放,则应该暂停 KillTimer(0); //删除定时器 SetDlgItemText(IDC_PLAY, _T("播放")); m_vlc.Pause(); //播放暂停 m_isPlay = !m_isPlay; return; } CString url; m_url.GetWindowTextW(url); bool ret = m_vlc.LoadMedia(url.GetBuffer()); //加载视频 if (!ret) { AfxMessageBox(L"加载媒体失败"); return; } ret = m_vlc.Play(); if (!ret) { AfxMessageBox(L"播放视频失败"); return; } m_len= 0; while (m_len == 0) { //循环直到获取到视频的长度 Sleep(20); m_len = m_vlc.GetLenth(); } if (m_len != -1) { //获取长度不出错则设置对应控件 m_pos.SetRange(0, m_len); m_pos.SetTicFreq(m_len / 10); CString time; time.Format(_T("00:00:00/%02d:%02d:%02d"), m_len / 3600, m_len / 60 % 60, m_len % 60); SetDlgItemText(IDC_ST_TIME, time); } SetDlgItemText(IDC_PLAY, _T("暂停")); m_isPlay = !m_isPlay; SetTimer(0, 500, NULL); } 暂停按钮 void CVideoPlayerDlg::OnBnClickedStop() { KillTimer(0); SetDlgItemText(IDC_PLAY, _T("播放")); m_isPlay = false; m_vlc.Stop(); } 进度条响应函数 void CVideoPlayerDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (nSBCode == 5) { TRACE("%d\n", nPos); CString time; time.Format(_T("%02d:%02d:%02d/%02d:%02d:%02d"),nPos/3600,nPos/60%60,nPos%60, m_len / 3600, m_len / 60 % 60, m_len % 60); SetDlgItemText(IDC_ST_TIME, time); m_vlc.SetPosition(nPos*1.0/m_len); } CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar); } 音量响应函数 void CVideoPlayerDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (nSBCode == 5) { CString strVol; strVol.Format(_T("%d%%"), 100 - nPos); SetDlgItemText(IDC_ST_VOLUME, strVol); m_vlc.SetVolume(100 - nPos); } CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar); } 播放速率响应事件 void CVideoPlayerDlg::OnCbnSelchangeCbRate() { int i=m_rate.GetCurSel(); switch (i) { case 0: m_vlc.SetRate(1); break; case 1: m_vlc.SetRate(1.5); break; case 2: m_vlc.SetRate(2); break; default: break; } } 定时器响应事件 void CVideoPlayerDlg::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 if (nIDEvent == 0) { //todo:获取播放状态 float pos=m_vlc.GetPosition(); m_pos.SetTic(int(pos*m_len)); CString time; time.Format(_T("%02d:%02d:%02d/%02d:%02d:%02d"), int(pos * m_len) / 3600, int(pos * m_len) / 60 % 60, int(pos * m_len) % 60, m_len / 3600, m_len / 60 % 60, m_len % 60); SetDlgItemText(IDC_ST_TIME, time); } CDialogEx::OnTimer(nIDEvent); }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有