VLC Extension Development FAQ: Networking and Header Limitations - opensubtitles/vlsub-opensubtitles-com GitHub Wiki
VLC extension development faces significant architectural and security-driven limitations that impact networking capabilities, particularly around custom HTTP headers and stream downloading. This comprehensive FAQ addresses the most common issues developers encounter and provides authoritative explanations from VLC's official documentation and developer community.
The fundamental limitation: VLC extensions cannot send custom HTTP headers due to architectural and security constraints built into VLC's HTTP access module.
Official explanation from VLC developer Rémi Denis-Courmont:
"The HTTP access doesn't provide for setting custom headers though. That was discussed several times: it is not possible. There are intrinsically no sane ways for the protocol state machine in the VLC access plugin to deal with headers whose semantics it ignores."
The HTTP access module implements a rigid protocol state machine that only supports predefined headers like http-user-agent
and http-referrer
. Custom headers would require the state machine to understand unknown header semantics, creating potential security and stability issues that VLC developers have deliberately avoided.
Technical details:
- Extensions use
vlc.sd.add_item()
with limited options:element.options = {":http-user-agent=QuickTime/7.5"}
- Only predefined HTTP options are supported:
http-user-agent
,http-referrer
,http-continuous
- The extension API intentionally does not expose custom header functionality
VLC extensions run in a highly restricted sandbox environment with severely limited networking capabilities:
Available functions:
-
vlc.stream()
for basic HTTP GET requests (no custom headers, no POST support) -
vlc.io
functions for file operations (added in VLC 3.0.2) - Limited access to VLC's internal modules through the global
vlc
table
Critical limitations of vlc.stream():
- No POST method support: Only GET requests are possible
- No custom headers: Cannot send Authorization, API keys, or other headers
- Performance issues: Significantly slower than external tools like curl
Removed capabilities: The critical vlc.net
module was removed in VLC 2.1.x for security reasons, breaking many extensions that relied on network functions like vlc.net.opendir()
.
Legacy vlc.net.connect_tcp limitations (for older VLC versions that still have it):
- No HTTPS support: Only supports plain HTTP connections, making it unsuitable for modern secure APIs
-
Same performance issues: 10x slower than curl, just like
vlc.stream()
- Security risks: Transmits data in plain text, vulnerable to interception
Security boundaries:
- No direct socket access or custom network programming
- All network operations must go through VLC's predefined protocols
- Extensions cannot bypass VLC's access modules or implement custom networking logic
Performance comparison: vlc.stream()
and legacy vlc.net.connect_tcp()
functions are approximately 10 times slower than external curl commands, creating a significant performance bottleneck for extensions.
Technical reasons for poor performance:
- Single-threaded execution: VLC extensions run in a single Lua thread without parallel processing
- VLC's internal HTTP stack: Uses VLC's media-optimized HTTP implementation, not designed for API calls
- Lua interpreter overhead: Additional processing layer between network calls and actual HTTP operations
- Memory management: Lua's garbage collection can cause delays during network operations
- Protocol state machine: VLC's rigid HTTP handling adds unnecessary overhead for simple API calls
Real-world impact:
-
API calls: Simple JSON API requests that take 100ms with curl can take 1+ seconds with
vlc.stream()
- Extension freezing: Slow network operations can cause the entire VLC interface to become unresponsive
- User experience: Noticeable delays when extensions need to fetch data or authenticate
Why curl is always preferred: Despite the Windows terminal window issue, curl remains the preferred and most tested solution for VLC extension networking because:
- 10x performance advantage: Significantly faster than any VLC native function
- Full HTTP method support: POST, PUT, DELETE, PATCH, etc.
- HTTPS support: Secure connections that VLC's native functions cannot provide
- Custom headers: Complete header control for authentication and API requirements
- Battle-tested: Used by countless extensions and proven reliable across platforms
Supported methods: VLC extensions only support HTTP GET requests through vlc.stream()
.
Unsupported methods:
- POST: Cannot send form data or JSON payloads
- PUT: Cannot update resources
- DELETE: Cannot delete resources
- PATCH: Cannot perform partial updates
- HEAD: Cannot perform metadata-only requests
Workaround implications: Many modern APIs require POST requests for authentication, data submission, or security reasons. Extensions cannot interact with these APIs directly, forcing developers to use external tools or proxy solutions.
The problem: When VLC extensions call external curl commands on Windows using os.execute()
, visible command prompt windows appear, creating a poor user experience.
The Windows curl dilemma: This creates a no-win situation for Windows users:
- Fast curl with visible terminals: Use curl for 10x performance improvement but show annoying command windows
- Slow vlc.stream() without terminals: Use native VLC functions that are painfully slow and can freeze the interface
Technical causes:
- Windows path issues: Windows paths require proper escaping and may conflict with PowerShell aliases
-
PowerShell curl alias: Windows PowerShell aliases
curl
toInvoke-WebRequest
, causing conflicts -
Process execution:
os.execute()
on Windows doesn't provide native window hiding capabilities - Windows process model: Unlike Unix systems, Windows cannot easily hide child process windows from Lua
Attempted solutions that don't work:
-
os.execute()
with redirection: Still shows window briefly -
START /B command: Not accessible from Lua's
os.execute()
- PowerShell hidden execution: Requires complex command line escaping
- VBScript wrappers: Add complexity and security concerns
Workarounds for Windows curl issues:
-
Use curl.exe explicitly:
curl.exe
instead ofcurl
in PowerShell -
Remove PowerShell alias:
Remove-Item alias:curl
in PowerShell - Hidden window execution: Use batch scripts with hidden execution flags
- WSL approach: Use Windows Subsystem for Linux for native curl behavior
Example batch script solution:
@echo off
curl.exe -s -H "Authorization: Bearer token" "https://example.com/api" > output.txt 2>&1
Yes, several Windows-specific challenges exist:
- Path complexity: Windows paths are more complex than Unix systems
- Permission issues: UAC can interfere with extension installation
- Firewall restrictions: May block local proxy ports used in workarounds
- Antivirus interference: May flag proxy servers as suspicious
- PowerShell execution policies: May prevent script execution
- Terminal window problem: No clean way to hide curl command windows from extensions
The fundamental Windows dilemma: Extension developers face an impossible choice on Windows systems:
Option 1: Use vlc.stream() (Clean but Slow)
- ✅ No visible terminal windows
- ✅ Native VLC integration
- ❌ 10x slower performance
- ❌ Can freeze VLC interface
- ❌ No POST method support
- ❌ No custom headers
- ❌ No HTTPS support in legacy vlc.net functions
Option 2: Use curl via os.execute() (Fast but Ugly) - RECOMMENDED
- ✅ 10x faster performance
- ✅ Full HTTP method support
- ✅ Custom headers support
- ✅ HTTPS/TLS security
- ✅ Battle-tested and reliable
- ❌ Visible command prompt windows on Windows
- ❌ Platform-specific code required
Developer recommendations:
-
For simple GET requests: Use
vlc.stream()
despite performance penalty - For POST/API interactions: Use curl and warn Windows users about terminal windows
- For production extensions: Implement local proxy server as cleanest solution
- For personal use: Accept curl terminal windows as necessary evil
1. Local HTTP Proxy Approach (Most Effective)
Implement a local HTTP server that adds required headers and forwards requests to VLC:
Nginx proxy configuration:
server {
listen 8080;
location /proxy {
proxy_pass $arg_url;
proxy_set_header Authorization $arg_auth;
proxy_set_header X-Custom-Header $arg_header;
add_header Access-Control-Allow-Origin *;
}
}
Node.js/Express proxy example:
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
app.use('/proxy', createProxyMiddleware({
target: 'https://target-server.com',
changeOrigin: true,
onProxyReq: (proxyReq, req, res) => {
proxyReq.setHeader('Authorization', req.headers['x-auth']);
proxyReq.setHeader('Custom-Header', req.headers['x-custom']);
}
}));
2. XSPF Playlist Method (Limited but Reliable)
Create XSPF playlist files with embedded HTTP options:
<?xml version="1.0" encoding="UTF-8"?>
<playlist xmlns="http://xspf.org/ns/0/" xmlns:vlc="http://www.videolan.org/vlc/playlist/ns/0/" version="1">
<trackList>
<track>
<location>https://example.com/stream.m3u8</location>
<extension application="http://www.videolan.org/vlc/playlist/0">
<vlc:option>http-user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64)</vlc:option>
<vlc:option>http-referrer=https://example.com</vlc:option>
</extension>
</track>
</trackList>
</playlist>
Limitations: Only supports User-Agent and Referrer headers, no POST methods.
3. yt-dlp Integration
Use yt-dlp as an intermediary for complex streaming scenarios:
-
GitHub project:
robturner45/vlc-yt-dlp
- Handles authentication and custom headers automatically
- Note: VLC 4.0 will include native yt-dlp support
No official plans exist for adding custom header support to VLC extensions. Multiple forum discussions confirm this is a known limitation with no roadmap items for resolution.
VLC developer guidance: For applications requiring custom headers, developers are consistently directed to:
- Native plugin development in C/C++ instead of Lua extensions
- External proxy solutions as documented above
- VLC's command-line interface with proper header options
Official VLC Resources:
- VLC Developer Documentation: https://wiki.videolan.org/
- VLC Extension API Reference: https://vlc.verg.ca (most comprehensive unofficial documentation)
- Official VLC Forums: https://forum.videolan.org/
- VLC GitHub Repository: https://github.com/videolan/vlc
- VLC Extension Examples: https://github.com/videolan/vlc/tree/master/share/lua/extensions
Community Resources:
- VLC Lua API Documentation: https://github.com/verghost/vlc-lua-docs (maintained by community developers)
- VLSub OpenSubtitles Extension: https://github.com/opensubtitles/vlsub-opensubtitles-com (modern example of workarounds)
Key GitHub Issues and Discussions:
-
Custom Headers Support Issue: https://github.com/kakone/VLC.MediaElement/issues/80
- Problem: "Unable to set headers like 'User-Agent' or any other authentications"
- Status: No resolution, repository archived in 2022
-
VLSub Extension Limitations: https://github.com/videolan/vlc/blob/master/share/lua/extensions/VLSub.lua
- Documents the removal of
vlc.net
module in VLC 2.1.x - Shows how extensions handle networking restrictions
- Documents the removal of
-
VLC Main Repository: https://github.com/videolan/vlc/tree/master/share/lua
- Contains official extension documentation and examples
- Shows the limited scope of extension APIs
VLC's extension limitations reflect deliberate architectural and security design decisions:
Security principles:
- Principle of least privilege: Extensions designed for UI enhancement, not low-level networking
- Reduced attack surface: Prevents extensions from introducing new attack vectors
- Sandbox integrity: Maintains isolation between extensions and core system
Historical context: VLC has had security vulnerabilities in HTTP parsing, format strings, and buffer overflows. The extension sandbox prevents these issues from being exploited through extension code.
Architectural consistency: VLC's modular design requires networking features to be implemented in C modules, not Lua extensions, maintaining code quality and security review processes.
Recommended development approaches:
- LibVLC Integration: Use LibVLC directly in applications requiring custom networking
- VLC HTTP Interface: Use VLC's built-in HTTP server interface for custom control
- Core Module Development: Implement custom access modules in C for advanced use cases
- External Application Integration: Build separate applications that communicate with VLC
Future outlook: VLC 4.0's native yt-dlp support will address many custom header limitations, making it the recommended long-term solution for complex streaming scenarios.
VLC extension development limitations around custom HTTP headers, POST methods, and networking performance are fundamental architectural constraints, not bugs to be fixed. These restrictions prioritize security and stability over extensibility, reflecting VLC's mature approach to media player security.
The Windows terminal window problem represents a particularly frustrating limitation where developers must choose between performance and user experience, with no clean solution available within VLC's extension framework.
For developers: Accept these limitations as design constraints and implement solutions using local proxies, external tools, or native VLC plugin development. The workarounds documented here represent the current best practices for working within VLC's security model while achieving custom networking functionality. On Windows, be prepared to make difficult trade-offs between performance and user experience.