<备忘1005> VLC代码分析之一

本文详细介绍了VLC多媒体框架的优势、目录结构、核心对象、以及如何构建一个基本播放器。深入探讨了VLC的系统架构、跨平台支持、编译系统、社区活跃度,并强调了学习其类对象架构、观察者模式、插件管理系统的重要性。文章还揭示了VLC代码的复杂性与清理难度,以及如何通过libVLC、libvlc_media_t、libvlc_media_player_t等关键组件进行多媒体内容的管理和播放。

0. 起因

   VLC最近出了2.0版本,决定今年深入掌握之,从分析代码开始,以此为备忘。


1. 概述

   VLC多媒体框架的优点是:1.系统更加紧凑、高效;2.跨平台支持好,特别是桌面平台(包括Windows、Mac);
3. 编译系统完善,很容易可以构造出支持Windows,linux的版本;4. 社区活跃,长期技术更新支持有保证。

   整个VLC是以libvlc和libvlccore以及第三方插件组成,前端是独立的。据悉VLC C源码是黑客级别,本人看了多
眼之后,深以为然,包括有:类对象架构,观察者模式,插件管理系统等值得学习的代码。另外一方面,整个代
码要消化和理解也是一件不容易的事情。而且由于历史原因,整个VLC代码到处充满了垃圾和无用的代码,估计
清理起来也非常麻烦。


2. 目录说明 ( 以 vlc-2.0.0 为准)

  • include/                         libvlccore 库的头文件,编写自己的插件也是需要包含这里
  • include/vlc                     libVLC头文件,如果仅仅使用libvlc开发,需要包含这里
  • bin                                 vlc程序代码,即原生GUI前端程序代码
  • lib                                  libVLC接口实现代码
  • compat                          跨 OS 代码
  • contrib                           第三方库的针对VLC的patch以及编译脚本
  • extras                            一些不太常用的辅助工具以及脚本
  • modules                        将各种第三方库封装为VLC的插件,按目录区分功能,如demux,video_filter等等
  • src                                 libvlccore实现,是vlc架构最重要部分

主要需要重点学习和关注的是:lib src两个目录之下的代码,这个两个目录也是整个vlc项目的核心。


3.    核心对象

使用libVLC构建一个最简单的播放器只需要调用下面间的API

    _vlcinstance = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
    _mp = libvlc_media_player_new (_vlcinstance);   
    libvlc_media_player_set_xwindow (_mp, windid );
    _msource = libvlc_media_new_location(_vlcinstance, "./demo.mp4");
    libvlc_media_player_set_media (_mp, _msource);
    ibvlc_media_player_play (_mp);

首先通过libvlc_new构造一个全局的instance对象,这个指针可以看作VLC context的handler.  整个VLC对象使用
XXX_new , XXX_release, XXX_retain 三个函数来管理对象的创建销毁以及引用,针对每个对象使用ref_count记录
指针引用次数,这样可以调用XXX_release函数多次,在最后一次进行真正的资源释放工作。 libvlc_instance_t 对
象组成如下,包括两个核心功能的顶层指针(核心对象一个是管理播放,一个是管理流媒体服务)。 

libvlc_instance对象组成
libvlc_int_t *p_libvlc_int;
libvlc_vlm_t  libvlc_vlm;
unsigned      ref_count;
vlc_mutex_t   instance_lock;






   为了完成播放人物还需libvlc_media_player_t 以及 libvlc_media_t 两个对象,这个两个对象都是从libvlc_instance对象
创建,其中libvlc_media_t封装了多媒体对象,可以是一个文件,一个URL或者一个媒介(如DVD)。 libvlc_media_player
对象则封装播放相管内容。

首先看看 libvlc_media_t 对象,主要组成如下:

libvlc_media对象组成
 //指向顶层指针
int                i_refcount;
libvlc_instance_t *p_libvlc_instance;   
//播放对象描述
input_item_t      *p_input_item;
libvlc_media_list_t *p_subitems;
void *p_user_data;
//控制变量
libvlc_event_manager_t * p_event_manager;
vlc_cond_t parsed_cond;
vlc_mutex_t parsed_lock;
//内置变量
bool is_parsed;
bool has_asked_preparse;

接下来就是最重要libvlc_player对象的组成了:

libvlc_player对象组成
int                i_refcount;
libvlc_instance_t * p_libvlc_instance;
vlc_mutex_t        object_lock;
libvlc_media_t * p_md;
libvlc_event_manager_t * p_event_manager;
    struct
    {   
        input_thread_t   *p_thread;
        input_resource_t *p_resource;
        vlc_mutex_t       lock;
    } input;










其中最最重要的就是这个 struct  input结构体,几乎所有重要的内容都在这个结构体内部,是理解整个VLC的核心,VLC内
主要的对象Access, Stream, Demuxer, Decoder, Vout, Aout全部都包含在input_thread, input_resource内。


[未完待续]


以下是基于Java(Maven)搭建Nginx和FFmpeg实现大华或海康摄像头流媒体直播的详细步骤: ### 1. 确认摄像头流是否可播放 打开vlc播放器,选择【媒体 --> 打开网络串流】,输入流地址。对于大华摄像头,其rtsp流地址格式为【rtsp://账号:密码@IP地址:544/cam/realmonitor?channel=1&subtype=0】,端口号默认544,通道号channel默认1,主码流为 0(即subtype=0),辅码流为1(即subtype=1)。若能正常播放,则可继续后续操作;若不能,需确认rtsp协议是否正确 。 ### 2. 安装和配置Nginx与FFmpeg 将nginx、ffmpeg解压后放置C盘根目录。配置环境变量path,添加路径:C:\ffmpeg\bin 。 ### 3. 创建Java(Maven)项目 可以使用IDE(如IntelliJ IDEA或Eclipse)创建一个新的Maven项目。在`pom.xml`文件中添加必要的依赖,例如用于执行系统命令的依赖: ```xml <dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-exec</artifactId> <version>1.3</version> </dependency> </dependencies> ``` ### 4. 编写Java代码实现流转发 通过Java代码调用FFmpeg命令将摄像头的RTSP流转发到Nginx服务器。以下是示例代码: ```java import org.apache.commons.exec.CommandLine; import org.apache.commons.exec.DefaultExecutor; import org.apache.commons.exec.ExecuteException; import java.io.IOException; public class StreamForwarder { public static void main(String[] args) { String rtspUrl = "rtsp://账号:密码@IP地址:544/cam/realmonitor?channel=1&subtype=0"; String nginxRtmpUrl = "rtmp://localhost/live/stream"; String ffmpegCommand = "ffmpeg -i " + rtspUrl + " -c copy -f flv " + nginxRtmpUrl; CommandLine cmdLine = CommandLine.parse(ffmpegCommand); DefaultExecutor executor = new DefaultExecutor(); try { executor.execute(cmdLine); } catch (ExecuteException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } ``` ### 5. 配置Nginx支持RTMP 在Nginx的配置文件`nginx.conf`中添加RTMP模块的配置: ```plaintext rtmp { server { listen 1935; chunk_size 4000; application live { live on; record off; } } } ``` 重启Nginx服务器使配置生效。 ### 6. 测试直播流 打开支持RTMP流播放的播放器(如VLC),输入`rtmp://localhost/live/stream`,若能正常播放,则说明流媒体直播搭建成功。 添加html代码用来展示直播流
最新发布
12-03
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值