LibVLC基于许多独立的模块,就像大多数竞争的多媒体框架一样。每个模块都提供特定的功能。
本文的重点是向VLC(或任何其他LibVLC应用程序)添加一个新模块(也称为插件)。您需要先阅读VLC核心和模块以及VLC如何加载模块,否则您将无法充实新模块的内容。
树内和树外模块
大多数现有的VLC模块作为源代码提供在主VLC源代码库(以及源tarballs)的目录模块中。它们与VLC内核同时编译,通常与VLC二进制软件包和安装程序一起分发。这些模块在树模块中调用。
但是,也可以在VLC之外编写和编译VLC模块。与在树中开发模块相比,它有一些优点和缺点:
编译速度要快得多(VLC和其他模块不包括在这个过程中)。
你可以使用你自己的版本控制系统,甚至完全没有。
版权许可证不需要遵守VideoLAN协会的要求就可以包含在VLC中。
源代码不需要提供,审查和接受的VLC开发人员。
发布计划独立于VLC发布。无论VLC发布计划如何,模块的新版本都可以随时发布。
至少在理论上可以使用不同的编程语言(主要的VLC代码库仅使用C、C++和Lua,以及MaOSO目标C)。
该模块可以使用VLC所依赖的软件库。
VLC开发人员不会审查代码,这将是提高代码质量的好机会。
VLC翻译人员将不负责模块的本地化(如适用)。VLC用许多语言翻译。
模块不能通过videolan.org网站分发,并且使用诸如bug跟踪程序和构建机器人等可视局域网基础设施。
模块将仅与已编译的特定VLC(主要)版本一起工作。例如,为VLC 1.1.x编译的模块将无法与VLC 1.0.x或VLC 2.0.x一起工作。
该模块将仅适用于它编译的特定操作系统和体系结构。例如,Windows 32位模块只适用于Windows 32位版本的VLC。VLC支持多种不同的操作系统和体系结构组合。
/**
* @file hello.c
* @brief Hello world interface VLC module example
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
/* VLC core API headers */
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_interface.h>
/* Internal state for an instance of the module */
struct intf_sys_t
{
char *who;
};
/**
* Starts our example interface.
*/
static int Open(vlc_object_t *obj)
{
intf_thread_t *intf = (intf_thread_t *)obj;
/* Allocate internal state */
intf_sys_t *sys = malloc(sizeof (*sys));
if (unlikely(sys == NULL))
return VLC_ENOMEM;
intf->p_sys = sys;
/* Read settings */
char *who = var_InheritString(intf, "hello-who");
if (who == NULL)
{
msg_Err(intf, "Nobody to say hello to!");
goto error;
}
sys->who = who;
msg_Info(intf, "Hello %s!", who);
return VLC_SUCCESS;
error:
free(sys);
return VLC_EGENERIC;
}
/**
* Stops the interface.
*/
static void Close(vlc_object_t *obj)
{
intf_thread_t *intf = (intf_thread_t *)obj;
intf_sys_t *sys = intf->p_sys;
msg_Info(intf, "Good bye %s!", sys->who);
/* Free internal state */
free(sys->who);
free(sys);
}
/* Module descriptor */
vlc_module_begin()
set_shortname(N_("Hello"))
set_description(N_("Hello interface"))
set_capability("interface", 0)
set_callbacks(Open, Close)
set_category(CAT_INTERFACE)
add_string("hello-who", "world", "Target", "Whom to say hello to.", false)
vlc_module_end ()
现在解释下代码
一个VLC媒体播放器模块必须包括一个描述本身,它接受的参数。
模块描述符以以下内容开头:
vlc_module_begin()
你应该设置一些关于你的模块的基本信息。这适用于dvdread模块:
set_shortname(N_("DVD without menus"))
set_description(N_("DVDRead Input"))
set_category(CAT_INPUT)
set_subcategory(SUBCAT_INPUT_ACCESS)
请注意,使用N_(“”) 创建需要由gettext翻译的字符串。
能力和得分
定义示例:
set_capability("interface", 0)
这定义了一个“接口”功能模块,得分为0。
能力决定了我们要处理的模块的类型。它可以是一个访问,一个解复用器,一个解码器,一个接口等,现在是时候重新阅读如何VLC加载模块。
如果VLC需要加载一个特定的名称,它将按名称加载它,VLC直接打开这个模块
如果VLC需要一种类型的模块(“我需要一个解码器”),VLC将以递减的分数顺序加载与此功能匹配的所有模块,直到一个模块的Open()函数(见下文)返回VLC\ U SUCCESS。
查看VLC的主要功能类型。
分数应该是整数,并且与同一类别中的其他分数相关。得分0是一个特例。
配置类别和子类别
您应该使用预定义的类别之一进行配置。配置类别和子类别指定模块在首选项UI对话框中的显示位置。
配置类别包括:
您还应该使用预定义的子类别之一。有关所有配置类别和子类别的定义,请参见include/vlc_configuration.h。
您可能需要选项来配置模块的运行时行为。定义新选项很容易。
所有选项定义都采用以下参数列表:
add_integer(name, value, text, longtext, advanced)
name是在配置中标识此参数的字符串。此名称在命令提示下用于设置配置值。
值是此参数的默认值,
text A是输入参数的简短描述,使用_(“”)创建需要翻译的字符串,
longtext一个完整的参数描述,使用_(“”)创建一个需要翻译的字符串,
高级布尔值,高级配置。如果为TRUE,则仅当使用—advanced标志时才会显示此参数。