导航:[首页]->[linux]->[Linux编译原生vlc]

##下载源码

#!/bin/bash
#安装依赖工具
apt-get install git libtool build-essential pkg-config autoconf
apt-get install subversion yasm cvs cmake libpcsclite-dev
#下载源码
git clone git://git.videolan.org/vlc.git
cd vlc
./bootstrap

也可以直接下载源码包,经测试,会快很多。

##安装依赖库

# 注意不是apt-get install build-dep,另外这个命令会去墙外的地址下东西,代理是必须的
apt-get build-dep vlc
cd contrib
mkdir native
cd native
../bootstrap
make

##编译

运行命令./configure –help,根据你的功能需要,配置选项。例如

./configure --disable-qt \
	--enable-static=false \
	--disable-nls \
	--disable-debug \
	--disable-gprof \
	--disable-cprof \
	--disable-coverage \
	--disable-lua \
	--disable-httpd \
	--disable-dc1394 \
	--disable-dv1394 \
	--disable-dvdread \
	--disable-dvdnav \
	--disable-bluray \
	--disable-smbclient \
	--disable-sftp \
	--disable-vcd \
	--disable-vcdx \
	--disable-screen \
	--disable-vnc \
	--disable-freerdp \
	--disable-chromaprint \
	--disable-chromecast
make

若希望放入正式的环境中,需要添加–libdir=/usr/lib/ 以便vlc从/usr/lib/vlc/plugins中去查找插件,具体可以configure之后,查看src/Makefile中的定义

/**
 * Enumerates all dynamic plug-ins that can be found.
 *
 * This function will recursively browse the default plug-ins directory and any
 * directory listed in the VLC_PLUGIN_PATH environment variable.
 * For performance reasons, a cache is normally used so that plug-in shared
 * objects do not need to loaded and linked into the process.
 */
static void AllocateAllPlugins (vlc_object_t *p_this)
{
	/* Contruct the special search path for system that have a relocatable
	 * executable. Set it to <vlc path>/plugins. */
	char *vlcpath = config_GetLibDir ();
	if (likely(vlcpath != NULL)
	 && likely(asprintf (&paths, "%s" DIR_SEP "plugins", vlcpath) != -1))
	{
		AllocatePluginPath (p_this, paths, mode);
		free( paths );
	}

/**
 * Determines the architecture-dependent data directory
 *
 * @return a string (always succeeds).
 */
char *config_GetLibDir (void)
{
	return strdup (PKGLIBDIR);
}

libdir = /usr/lib
vlclibdir = ${libdir}/${PKGDIR}
AM_CPPFLAGS = $(INCICONV) $(IDN_CFLAGS) -DMODULE_STRING=\"core\" \
	-DLOCALEDIR=\"$(localedir)\" -DPKGDATADIR=\"$(vlcdatadir)\" \
	-DPKGLIBDIR=\"$(vlclibdir)\" $(am__append_1) $(am__append_2)
PKGDIR = vlc

编译结束,会生成vlc、vlcstatic等可执行文件

##live555 bug 在live555的初始化代码中,有一段很挫的获取本机ip的代码,错误提示如下:

live555 This computer has an invalid IP address: 0.0.0.0

修改代码 vlc/contrib/native/live555/groupsock/GroupsockHelper.cpp

netAddressBits GetSelfIP()
{
	int newSocket = socket(AF_INET, SOCK_DGRAM, 0);
	if (newSocket < 0)
	{
		printf("unable to create datagram socket22222\n");
		return INADDR_ANY;
	}
	struct sockaddr_in fromAddr;
	fromAddr.sin_family=AF_INET;
	fromAddr.sin_port = htons(80);
	fromAddr.sin_addr.s_addr= inet_addr("8.8.8.8");
	if(connect(newSocket,(struct sockaddr*)&fromAddr,sizeof(fromAddr)) == -1)
	{
			printf("%d %d|%s\n",__LINE__,errno,strerror(errno));
			closeSocket(newSocket);
			return INADDR_ANY;
	}

	struct sockaddr_in myAddr;
	socklen_t myaddr_len_ = sizeof(myAddr);
	if(getsockname(newSocket,(struct sockaddr*)&myAddr,&myaddr_len_) == -1)
	{
		printf("%d %d|%s\n",__LINE__,errno,strerror(errno));
		closeSocket(newSocket);
		return INADDR_ANY;
	}
	closeSocket(newSocket);
	return myAddr.sin_addr.s_addr;
}

netAddressBits ourIPAddress(UsageEnvironment& env) {
#if 1
	netAddressBits res_ = GetSelfIP();
	if(res_ == INADDR_ANY)
		return inet_addr("127.0.0.1");
	else
		return res_;
#else
	static netAddressBits ourAddress = 0;
	int sock = -1;
	struct in_addr testAddr;

	if (ReceivingInterfaceAddr != INADDR_ANY) {
		// Hack: If we were told to receive on a specific interface address, then
		// define this to be our ip address:
		ourAddress = ReceivingInterfaceAddr;
	}

	if (ourAddress == 0) {
		// We need to find our source address
		struct sockaddr_in fromAddr;
		fromAddr.sin_addr.s_addr = 0;

		// Get our address by sending a (0-TTL) multicast packet,
		// receiving it, and looking at the source address used.
		// (This is kinda bogus, but it provides the best guarantee
		// that other nodes will think our address is the same as we do.)
		do {
			loopbackWorks = 0; // until we learn otherwise

			testAddr.s_addr = our_inet_addr("228.67.43.91"); // arbitrary
			Port testPort(15947); // ditto

			sock = setupDatagramSocket(env, testPort);
			if (sock < 0)
				break;

			if (!socketJoinGroup(env, sock, testAddr.s_addr))
				break;

			unsigned char testString[] = "hostIdTest";
			unsigned testStringLength = sizeof testString;

			if (!writeSocket(env, sock, testAddr, testPort, 0, testString,
					testStringLength))
				break;

			// Block until the socket is readable (with a 5-second timeout):
			fd_set rd_set;
			FD_ZERO(&rd_set);
			FD_SET((unsigned )sock, &rd_set);
			const unsigned numFds = sock + 1;
			struct timeval timeout;
			timeout.tv_sec = 5;
			timeout.tv_usec = 0;
			int result = select(numFds, &rd_set, NULL, NULL, &timeout);
			if (result <= 0)
				break;

			unsigned char readBuffer[20];
			int bytesRead = readSocket(env, sock, readBuffer, sizeof readBuffer,
					fromAddr);
			if (bytesRead != (int) testStringLength
					|| strncmp((char*) readBuffer, (char*) testString,
							testStringLength) != 0) {
				break;
			}

			// We use this packet's source address, if it's good:
			loopbackWorks = !badAddressForUs(fromAddr.sin_addr.s_addr);
		} while (0);

		if (sock >= 0) {
			socketLeaveGroup(env, sock, testAddr.s_addr);
			closeSocket(sock);
		}

		if (!loopbackWorks)
			do {
				// We couldn't find our address using multicast loopback,
				// so try instead to look it up directly - by first getting our host name, and then resolving this host name
				char hostname[100];
				hostname[0] = '\0';
				int result = gethostname(hostname, sizeof hostname);
				if (result != 0 || hostname[0] == '\0') {
					env.setResultErrMsg("initial gethostname() failed");
					break;
				}

				// Try to resolve "hostname" to an IP address:
				NetAddressList addresses(hostname);
				NetAddressList::Iterator iter(addresses);
				NetAddress const* address;

				// Take the first address that's not bad:
				netAddressBits addr = 0;
				while ((address = iter.nextAddress()) != NULL) {
					netAddressBits a = *(netAddressBits*) (address->data());
					if (!badAddressForUs(a)) {
						addr = a;
						break;
					}
				}

				// Assign the address that we found to "fromAddr" (as if the 'loopback' method had worked), to simplify the code below:
				fromAddr.sin_addr.s_addr = addr;
			} while (0);

		// Make sure we have a good address:
		netAddressBits from = fromAddr.sin_addr.s_addr;
		if (badAddressForUs(from)) {
			char tmp[100];
			sprintf(tmp, "This computer has an invalid IP address: %s",
					AddressString(from).val());
			env.setResultMsg(tmp);
			from = 0;
		}

		ourAddress = from;

		// Use our newly-discovered IP address, and the current time,
		// to initialize the random number generator's seed:
		struct timeval timeNow;
		gettimeofday(&timeNow, NULL);
		unsigned seed = ourAddress ^ timeNow.tv_sec ^ timeNow.tv_usec;
		our_srandom(seed);
	}
	return ourAddress;
#endif
}

##参考

  1. https://wiki.videolan.org/UnixCompile/
  2. http://jeremiah.blog.51cto.com/539865/275791