Skip to content

Commit 6df8bf5

Browse files
FrayxRulezclaude
andcommitted
Consume libvlc and webrtc as prebuilt binaries
Both were built from source as part of setting up a checkout. libvlc meant an 8.8 GB submodule, Docker and the VideoLAN contrib toolchain; webrtc meant depot_tools, a ~1.5 hour sync, ~20 GB of disk and a multi-hour build, ending in absolute paths to C:\webrtc hardcoded in two project files. Both change about once a year. They are vcpkg overlay ports now, downloading an archive for the architecture being built and verifying it against a recorded SHA512. The sources, the scripts that produce the archives and the patches they need moved to UnigramDev/deps, and the archives are published as releases there, each naming the fork commit it was built from. The libvlc port also has to place the plugin tree, which cannot be flattened: the plugins' paths are recorded in the generated plugins.dat cache, so they reach the package as plugins\<category>\<name>.dll through Content items rather than the flat copy the other dependencies use. VcpkgAutoLink is off. It put every .lib in the installed tree on every link line, which since webrtc arrived meant Telegram.Native scanning a 339 MB static library it has no reference into. Each project now names what it links, derived from what the binaries actually import. tgcalls and Telegram.Native.Calls include libyuv by its full path. webrtc carries a patched copy whose ConvertToI420 takes three extra parameters, and vcpkg's libyuv port supplies the stock one, so a plain <libyuv.h> resolved to whichever include directory came first -- which was decided by a hardcoded path that no longer exists. The three compiled files that used the ambiguous form now say which library they mean. Libraries/vlc and Libraries/webrtc are gone, submodule included. The VLC checkout the former held is an ordinary clone of the fork now, kept outside the repository. The instructions for building without WebRTC go too. Removing the project reference and the ENABLE_CALLS directive still compiles, but webrtc is listed in vcpkg.json, so the restore installs it for the triplet either way -- the download that section existed to avoid is spent before any project is built. Making it work again means a manifest feature, not a set of manual edits. duplicated-libraries.md records what the app now carries more than one copy of -- two ffmpeg builds, and opus and libyuv both as DLLs and inside webrtc.lib -- with the measurements behind it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent b5cdb0e commit 6df8bf5

38 files changed

Lines changed: 269 additions & 1546 deletions

‎.gitmodules‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
[submodule "Libraries/CoreWindowCustomDPI"]
1717
path = Libraries/CoreWindowCustomDPI
1818
url = https://github.com/ahmed605/CoreWindowCustomDPI.git
19-
[submodule "Libraries/vlc/vlc"]
20-
path = Libraries/vlc/vlc
21-
url = https://github.com/videolan/vlc.git
2219
[submodule "Libraries/tdlib"]
2320
path = Libraries/tdlib
2421
url = https://github.com/tdlib/td.git

‎Directory.Build.props‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@
4848
build, or a pass that only queries the project for its packaging outputs — and the DLLs
4949
then go missing from the appx with no error. -->
5050
<VcpkgApplocalDeps>false</VcpkgApplocalDeps>
51+
52+
<!-- Autolink puts every .lib in the installed tree on every link line, which since webrtc
53+
arrived means Telegram.Native scans a 339 MB static library it has no reference into.
54+
The libraries each project actually needs are listed in Directory.Build.targets. -->
55+
<VcpkgAutoLink>false</VcpkgAutoLink>
5156
</PropertyGroup>
5257

5358
<Import Project="$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.props"

‎Directory.Build.targets‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,37 @@
33
<Import Project="$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.targets"
44
Condition="'$(UnigramUsesVcpkg)' == 'true' And '$(MSBuildProjectExtension)' == '.vcxproj' And Exists('$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.targets')" />
55

6+
<!--
7+
With VcpkgAutoLink off, each project names the libraries it links. The lists below were
8+
derived from the imports of the binaries built with autolink on, so they are what the linker
9+
actually resolved rather than what the manifest happens to contain:
10+
11+
Telegram.Native libvlc, avcodec, avformat, avutil, swscale, libyuv, lz4, ogg, opus,
12+
zlib, and ZXing (static, so it leaves no import to observe)
13+
Telegram.Native.Calls webrtc (static, and the source of its libyuv and opus), avcodec,
14+
avformat, avutil, zlib
15+
16+
boost-regex appears in neither: it is header-only at this version and produces no .lib, which
17+
is why libprisma compiles against it without linking anything.
18+
19+
Only lz4 and zlib differ by configuration.
20+
-->
21+
<ItemDefinitionGroup Condition="'$(MSBuildProjectName)' == 'Telegram.Native'">
22+
<Link>
23+
<AdditionalDependencies>avcodec.lib;avformat.lib;avutil.lib;swscale.lib;libvlc.lib;libvlccore.lib;libyuv.lib;ogg.lib;opus.lib;ZXing.lib;%(AdditionalDependencies)</AdditionalDependencies>
24+
<AdditionalDependencies Condition="'$(Configuration)' == 'Debug'">lz4d.lib;zlibd.lib;%(AdditionalDependencies)</AdditionalDependencies>
25+
<AdditionalDependencies Condition="'$(Configuration)' != 'Debug'">lz4.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
26+
</Link>
27+
</ItemDefinitionGroup>
28+
29+
<ItemDefinitionGroup Condition="'$(MSBuildProjectName)' == 'Telegram.Native.Calls'">
30+
<Link>
31+
<AdditionalDependencies>webrtc.lib;avcodec.lib;avformat.lib;avutil.lib;swscale.lib;%(AdditionalDependencies)</AdditionalDependencies>
32+
<AdditionalDependencies Condition="'$(Configuration)' == 'Debug'">zlibd.lib;%(AdditionalDependencies)</AdditionalDependencies>
33+
<AdditionalDependencies Condition="'$(Configuration)' != 'Debug'">zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
34+
</Link>
35+
</ItemDefinitionGroup>
36+
637
<Target Name="UnigramCheckVcpkgRoot" BeforeTargets="PrepareForBuild;BeforeBuild"
738
Condition="'$(UnigramUsesVcpkg)' == 'true'">
839
<Error Condition="'$(VcpkgRoot)' == ''"
@@ -60,4 +91,25 @@
6091
Text="No vcpkg runtime DLLs found in $(UnigramVcpkgBinDir). The package will be missing them at runtime." />
6192
</Target>
6293

94+
<!--
95+
libvlc's plugins are the one dependency that cannot be copied flat: their relative paths are
96+
recorded in the generated plugins.dat cache, so they have to reach the package as
97+
plugins\<category>\<name>.dll. ReferenceCopyLocalPaths flattens, hence Content with Link.
98+
99+
Only the app project packages content; libvlc.dll and libvlccore.dll themselves come from
100+
bin\ through the flat copy above.
101+
-->
102+
<Target Name="UnigramAddVlcPlugins" BeforeTargets="ResolveReferences"
103+
Condition="'$(UnigramUsesVcpkg)' == 'true' And '$(MSBuildProjectExtension)' == '.csproj'">
104+
<ItemGroup>
105+
<_UnigramVlcPlugin Include="$(UnigramVcpkgInstalledDir)share\libvlc\plugins\**\*" />
106+
<Content Include="@(_UnigramVlcPlugin)">
107+
<Link>plugins\%(RecursiveDir)%(Filename)%(Extension)</Link>
108+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
109+
</Content>
110+
</ItemGroup>
111+
<Warning Condition="'@(_UnigramVlcPlugin)' == ''"
112+
Text="No libvlc plugins found in $(UnigramVcpkgInstalledDir)share\libvlc\plugins. Video playback will fail at runtime." />
113+
</Target>
114+
63115
</Project>

‎Documentation/Build-instructions.md‎

Lines changed: 14 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,8 @@ Two things about that checkout matter:
6161
```
6262
The build checks this before doing anything and tells you the exact commands if it is behind.
6363

64-
That is the whole setup. There is no port to edit by hand, no patch to apply, and
65-
**do not** run `vcpkg integrate install` — the repository disables the machine-wide
66-
integration so that it always builds against its own pinned commit.
64+
That is the whole setup. **Do not** run `vcpkg integrate install`: the repository disables the
65+
machine-wide integration so that it always builds against its own pinned commit.
6766

6867
Everything else comes from `vcpkg.json` in the repository root, which is a
6968
[manifest](https://learn.microsoft.com/vcpkg/consume/manifest-mode): it pins the vcpkg commit
@@ -99,72 +98,21 @@ The script picks up `VCPKG_ROOT` and builds against the manifest in the reposito
9998
openssl and zlib are the same builds the app links. You can choose to build both `x64` and
10099
`arm64` or just the architecture you need.
101100

102-
### LibVLC
103-
Unigram uses LibVLC to play videos and audio in the app. We can't use the system provided media player doesn't meet the app quality expectations.
104-
The app is currently using version `3.0.22-rc1` with some patches applied on top, and can be built by running the script `build.ps1` located in `Unigram repository\Libraries\vlc`.
101+
### LibVLC and WebRTC
105102

106-
Building LibVLC requires [Docker](https://docs.docker.com/desktop/setup/install/windows-install/) to be installed and running.
103+
LibVLC plays video and audio, and WebRTC backs calls and video chats. Both arrive as prebuilt
104+
binaries through the same manifest as everything else, as overlay ports in
105+
`Libraries\vcpkg-ports`. The build downloads an archive for the architecture it is building,
106+
verifies it against a SHA512 recorded in the port, and caches it — so there is nothing to install
107+
or configure for either.
107108

108-
```shell
109-
powershell -ExecutionPolicy ByPass ./build.ps1 -arch x64,ARM64
110-
```
111-
112-
The script will automatically apply the needed patches to libvlc (that comes as a submodule when you clone the repository) and create a NuGet package inside the `Libraries` folder.
113-
114-
For reference, this is the list of VLC plugins currently needed by Unigram to properly work:
115-
- access\libhttps_plugin.dll
116-
- access\libhttp_plugin.dll
117-
- access\libimem_plugin.dll
118-
- audio_filter\libaudio_format_plugin.dll
119-
- audio_filter\libsamplerate_plugin.dll
120-
- audio_filter\libscaletempo_plugin.dll
121-
- audio_filter\libtrivial_channel_mixer_plugin.dll
122-
- audio_filter\libugly_resampler_plugin.dll
123-
- audio_mixer\libfloat_mixer_plugin.dll
124-
- audio_output\libwasapi_plugin.dll
125-
- audio_output\libwinstore_plugin.dll
126-
- codec\libavcodec_plugin.dll
127-
- codec\libd3d11va_plugin.dll
128-
- codec\libdav1d_plugin.dll
129-
- codec\libflac_plugin.dll
130-
- codec\libfaad_plugin.dll
131-
- codec\libmpg123_plugin.dll
132-
- codec\libopus_plugin.dll
133-
- demux\libes_plugin.dll
134-
- demux\libflacsys_plugin.dll
135-
- demux\libmp4_plugin.dll
136-
- demux\libogg_plugin.dll
137-
- demux\libps_plugin.dll
138-
- packetizer\libpacketizer_flac_plugin.dll
139-
- packetizer\libpacketizer_h264_plugin.dll
140-
- packetizer\libpacketizer_mpegaudio_plugin.dll
141-
- packetizer\libpacketizer_mpegvideo_plugin.dll
142-
- stream_filter\libcache_block_plugin.dll
143-
- stream_filter\libcache_read_plugin.dll
144-
- stream_filter\librecord_plugin.dll
145-
- stream_filter\libskiptags_plugin.dll
146-
- text_renderer\libtdummy_plugin.dll
147-
- video_chroma\libswscale_plugin.dll
148-
- video_chroma\libyuvp_plugin.dll
149-
- video_output\libdirect3d11_plugin.dll
150-
151-
### WebRTC
152-
Unigram uses WebRTC for calls and video chats. Since WebRTC doesn't currently support UWP, you must use our fork to build it.
153-
1. Click on Start Menu → Visual Studio 2022 → x64 Native Tools Command Prompt for VS 2022.
154-
2. Navigate to .\Unigram\Libraries\webrtc
155-
3. Execute `.\acquire.cmd`. This will clone WebRTC source code to `C:\webrtc`, and it will take a while (~1.5h)
156-
4. Execute `.\build.cmd "$arch$" "$config$"`. Replace `$arch$` with either `x64`, `win32` or `arm64` depending on your build target. `$config$` can be set to either `release` or `debug`.
157-
158-
⚠️ Note that WebRTC build instructions are based on [WinRTC](https://github.com/microsoft/winrtc/tree/master/patches_for_WebRTC_org/m84).
159-
160-
### Building without WebRTC
161-
Since compiling WebRTC is time and resources consuming, it is possible to build the app without calls support:
162-
- Locate Telegram > References and remove `Telegram.Native.Calls` from the list.
163-
- From Telegram > Properties > Build, remove `ENABLE_CALLS` directive.
164-
- Exclude from the project the following files:
165-
- Controls/Cells/GroupCallParticipantGridCell.xaml
166-
- Views/Calls/*
109+
They are built from [UnigramDev/vlc](https://github.com/UnigramDev/vlc) and
110+
[UnigramDev/webrtc-uwp](https://github.com/UnigramDev/webrtc-uwp); the WebRTC fork follows
111+
[WinRTC](https://github.com/microsoft/winrtc/tree/master/patches_for_WebRTC_org/m84). Each
112+
release names the commit it was built from.
167113

114+
To change either one, see [UnigramDev/deps](https://github.com/UnigramDev/deps), which holds the
115+
build scripts, the patches and the packaging, and documents how to publish a new archive.
168116

169117
### Code fails to build?
170118

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Prebuilt: libvlc is built from the UnigramDev/vlc fork by the scripts in UnigramDev/deps and
2+
# published as a release archive there. Building it here is not practical -- it needs Docker and
3+
# the VideoLAN contrib toolchain -- and the result changes about once a year.
4+
5+
vcpkg_check_linkage(ONLY_DYNAMIC_LIBRARY)
6+
7+
# VLC's UWP build does not pass /APPCONTAINER when linking libvlc.dll and libvlccore.dll. These
8+
# are the same binaries the app ships today through the NuGet package, so this is the status quo
9+
# rather than a regression -- but it is worth knowing if store certification ever objects.
10+
set(VCPKG_POLICY_SKIP_APPCONTAINER_CHECK enabled)
11+
12+
if(VCPKG_TARGET_ARCHITECTURE STREQUAL "x64")
13+
set(LIBVLC_SHA512 c451cdbe610bc6fe16c4c7e39f2a702bd288d5f439f6983887bc4a26d21f7f7c2e7d6b983b582f2a634fa3e9f840206cced3618d03b5b6ae4f1bd537f39d0395)
14+
elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64")
15+
set(LIBVLC_SHA512 ab0357f90f207068d00d4325de6809a595b1098c57fec9cc74382140af7d10b6faeb2b7489951515e9e3b8a707ee444a9d28c880371d49bb4524bce9c5419aed)
16+
else()
17+
message(FATAL_ERROR "libvlc: no prebuilt archive for ${VCPKG_TARGET_ARCHITECTURE}")
18+
endif()
19+
20+
vcpkg_download_distfile(ARCHIVE
21+
URLS "https://github.com/UnigramDev/deps/releases/download/libvlc-${VERSION}-2/libvlc-${VERSION}-${VCPKG_TARGET_ARCHITECTURE}-uwp.zip"
22+
FILENAME "libvlc-${VERSION}-${VCPKG_TARGET_ARCHITECTURE}-uwp.zip"
23+
SHA512 "${LIBVLC_SHA512}"
24+
)
25+
26+
vcpkg_extract_source_archive(SOURCE_PATH
27+
ARCHIVE "${ARCHIVE}"
28+
NO_REMOVE_ONE_LEVEL
29+
)
30+
31+
file(COPY "${SOURCE_PATH}/include" DESTINATION "${CURRENT_PACKAGES_DIR}")
32+
file(COPY "${SOURCE_PATH}/lib" DESTINATION "${CURRENT_PACKAGES_DIR}")
33+
file(COPY "${SOURCE_PATH}/bin" DESTINATION "${CURRENT_PACKAGES_DIR}")
34+
35+
# The plugins keep their directory structure: their relative paths are recorded in the generated
36+
# plugins.dat cache, so flattening them would invalidate it and cost a scan on every launch.
37+
file(COPY "${SOURCE_PATH}/share/libvlc" DESTINATION "${CURRENT_PACKAGES_DIR}/share")
38+
39+
# Upstream publishes release binaries only. vcpkg still expects a debug tree, and a Debug build of
40+
# the app has to link and load something -- these are C ABI DLLs, so the release build is correct
41+
# to use rather than merely tolerable.
42+
file(COPY "${CURRENT_PACKAGES_DIR}/lib" DESTINATION "${CURRENT_PACKAGES_DIR}/debug")
43+
file(COPY "${CURRENT_PACKAGES_DIR}/bin" DESTINATION "${CURRENT_PACKAGES_DIR}/debug")
44+
45+
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/copyright")
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "libvlc",
3+
"version": "3.0.23",
4+
"description": "LibVLC built for UWP from UnigramDev/vlc, with the plugin set Unigram needs.",
5+
"homepage": "https://github.com/UnigramDev/vlc",
6+
"license": "LGPL-2.1-or-later",
7+
"supports": "uwp & (x64 | arm64)"
8+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Prebuilt: webrtc is built from the UnigramDev/webrtc-uwp fork by the scripts in UnigramDev/deps
2+
# and published as release archives there. Building it from source needs depot_tools, a ~1.5 hour
3+
# sync and ~20 GB of disk, for a result that changes a few times a year.
4+
#
5+
# Headers and libraries are separate archives so that a build downloads only the configuration it
6+
# links: the two libraries are 85 MB and 135 MB compressed, against 18 MB of headers shared by all.
7+
8+
vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
9+
10+
set(WEBRTC_HEADERS_SHA512 1b2c5b0908eb6331323f1af1b6c45fdcf96ad4e2200b1bf62644ad3a6174251360bc9349445867850ceac05346f93d085db910552837a7511e95a01540338bea)
11+
12+
if(VCPKG_TARGET_ARCHITECTURE STREQUAL "x64")
13+
set(WEBRTC_RELEASE_SHA512 26149f89ca0fb2591c0c8a0f065147223d46b894df250eeb359c7d7366c5baec9d4aa57284a214e9baeb8272838d54c1361f8883ffcd3c2f58e3429a0579c16b)
14+
set(WEBRTC_DEBUG_SHA512 ad9476648d4aeec681df33222c9c57d53b02a6afe20ed289ae44de9b4225208a0ec00d69c1dfb3f847e5c770e93cc84c5ee485dac964570ec4e2c243a4cac53f)
15+
elseif(VCPKG_TARGET_ARCHITECTURE STREQUAL "arm64")
16+
set(WEBRTC_RELEASE_SHA512 af40752ab6d858d21359f7fd084cb72abb73c8c4e6ce5541f15645dc70a2a6affe0604b94995df3bcda9dbf5f4f69349addf080430cfd33001bcdd5c661d9d24)
17+
set(WEBRTC_DEBUG_SHA512 e9966685ed7db1b6169d903f9b74bd7165b19f83b697cc413f296328461c4dc8df3a8d7cb2fea80af48007b44ad50082b7e6d1fb1d9900e860891d83a6dceb2a)
18+
else()
19+
message(FATAL_ERROR "webrtc: no prebuilt archive for ${VCPKG_TARGET_ARCHITECTURE}")
20+
endif()
21+
22+
set(WEBRTC_BASE_URL "https://github.com/UnigramDev/deps/releases/download/webrtc-${VERSION}-1")
23+
24+
vcpkg_download_distfile(HEADERS_ARCHIVE
25+
URLS "${WEBRTC_BASE_URL}/webrtc-${VERSION}-headers.zip"
26+
FILENAME "webrtc-${VERSION}-headers.zip"
27+
SHA512 "${WEBRTC_HEADERS_SHA512}"
28+
)
29+
vcpkg_extract_source_archive(HEADERS_PATH ARCHIVE "${HEADERS_ARCHIVE}" NO_REMOVE_ONE_LEVEL)
30+
file(COPY "${HEADERS_PATH}/include" DESTINATION "${CURRENT_PACKAGES_DIR}")
31+
32+
# The three include roots the projects used to pass by hand -- the checkout root, abseil-cpp and
33+
# libyuv/include -- are collapsed into this one directory by the packaging script.
34+
35+
if(NOT VCPKG_BUILD_TYPE STREQUAL "debug")
36+
vcpkg_download_distfile(RELEASE_ARCHIVE
37+
URLS "${WEBRTC_BASE_URL}/webrtc-${VERSION}-${VCPKG_TARGET_ARCHITECTURE}-uwp-release.zip"
38+
FILENAME "webrtc-${VERSION}-${VCPKG_TARGET_ARCHITECTURE}-uwp-release.zip"
39+
SHA512 "${WEBRTC_RELEASE_SHA512}"
40+
)
41+
vcpkg_extract_source_archive(RELEASE_PATH ARCHIVE "${RELEASE_ARCHIVE}" NO_REMOVE_ONE_LEVEL)
42+
file(COPY "${RELEASE_PATH}/lib" DESTINATION "${CURRENT_PACKAGES_DIR}")
43+
endif()
44+
45+
if(NOT VCPKG_BUILD_TYPE STREQUAL "release")
46+
vcpkg_download_distfile(DEBUG_ARCHIVE
47+
URLS "${WEBRTC_BASE_URL}/webrtc-${VERSION}-${VCPKG_TARGET_ARCHITECTURE}-uwp-debug.zip"
48+
FILENAME "webrtc-${VERSION}-${VCPKG_TARGET_ARCHITECTURE}-uwp-debug.zip"
49+
SHA512 "${WEBRTC_DEBUG_SHA512}"
50+
)
51+
vcpkg_extract_source_archive(DEBUG_PATH ARCHIVE "${DEBUG_ARCHIVE}" NO_REMOVE_ONE_LEVEL)
52+
file(COPY "${DEBUG_PATH}/lib" DESTINATION "${CURRENT_PACKAGES_DIR}/debug")
53+
endif()
54+
55+
vcpkg_install_copyright(FILE_LIST "${HEADERS_PATH}/LICENSE")
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"name": "webrtc",
3+
"version-date": "2026-08-11",
4+
"description": "WebRTC built for UWP from UnigramDev/webrtc-uwp, as consumed by tgcalls.",
5+
"homepage": "https://github.com/UnigramDev/webrtc-uwp",
6+
"license": "BSD-3-Clause",
7+
"supports": "uwp & (x64 | arm64)"
8+
}

‎Libraries/vlc/0001-Fix-build-UWP.patch‎

Lines changed: 0 additions & 25 deletions
This file was deleted.

‎Libraries/vlc/0002-Print-plugin-file-name-on-load.patch‎

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)