vlc-android: 編譯自己的libvlc

在這里插入圖片描述

概述

VLC 媒體播放器作為一款由志愿者開發團隊精心維護的自由、開源且跨平臺的多媒體播放器,能輕松駕馭絕大多數多媒體文件,無論是本地磁盤中的視頻、音頻,還是來自網絡的流媒體協議. VLC for Android 支持網絡串流,無論是基于 HLS 的自適應流媒體,還是 DASH 流,都能穩定播放。對于有 NAS(網絡附屬存儲)設備,或者需要訪問共享驅動器的用戶而言,它也提供了便捷的瀏覽支持。在兼容性方面,其早期版本支持 Android 2.2 及以上,而當前版本則要求 Android 4.2 及更高版本,同時對 ARM v7、ARMv8/A arch 64、MIPS 和 x86 等多種硬件架構提供支持,甚至還兼容 Android TV ,大大拓展了其使用場景。

編譯環境
  • 系統: ubuntu 22.04
  • ndk: 27
  • gradle: 8.13
  • cmake: 4.0.3

編譯

環境依賴

sudo apt install automake ant autopoint cmake build-essential libtool-bin \patch pkg-config protobuf-compiler ragel subversion unzip git \openjdk-8-jre openjdk-8-jdk flex python wget

編譯命令:

# 設置AndroidSDK 和AndroidNDK
export ANDROID_NDK=~/Android/Sdk/ndk/27.0.12077973/
export ANDROID_SDK=~/Android/Sdk/
./buildsystem/compile.sh -l -a arm64

一些問題

1. cmake 3.22 太舊

	編譯vlc-android出錯:-- The C compiler identification is Clang 18.0.1-- The CXX compiler identification is Clang 18.0.1CMake Warning (dev) at path-to-Android/Sdk/ndk/27.0.12077973/build/cmake/flags.cmake:46 (if):Policy CMP0057 is not set: Support new IN_LIST if() operator.  Run "cmake--help-policy CMP0057" for policy details.  Use the cmake_policy command toset the policy and suppress this warning.IN_LIST will be interpreted as an operator when the policy is set to NEW.Since the policy is not set the OLD behavior will be used.Call Stack (most recent call first):/usr/share/cmake-3.22/Modules/Platform/Android-Clang.cmake:23 (include)/usr/share/cmake-3.22/Modules/Platform/Android-Clang-C.cmake:1 (include)/usr/share/cmake-3.22/Modules/CMakeCInformation.cmake:48 (include)CMakeLists.txt:3 (project)This warning is for project developers.  Use -Wno-dev to suppress it.CMake Error at /home/anson/Android/Sdk/ndk/27.0.12077973/build/cmake/flags.cmake:46 (if):if given arguments:"hwaddress" "IN_LIST" "ANDROID_SANITIZE"Unknown arguments specifiedCall Stack (most recent call first):/usr/share/cmake-3.22/Modules/Platform/Android-Clang.cmake:23 (include)/usr/share/cmake-3.22/Modules/Platform/Android-Clang-C.cmake:1 (include)/usr/share/cmake-3.22/Modules/CMakeCInformation.cmake:48 (include)CMakeLists.txt:3 (project)

下載新版本cmake 編譯安裝

2. /usr/bin/install: cannot stat ‘…/…/share/vlc.appdata.xml’: No such file or directory

	cp vlc/share/vlc.appdata.xml.in.in vlc/share/vlc.appdata.xml

3. kotlin-compiler-embeddable-1.6.10.jar 下載太慢

修改源:libvlcjni/build.gradle

	// Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript {ext.android_plugin_version = '8.11.0'ext.kotlin_version = '1.6.10'ext.kotlinx_version = '1.6.0'repositories {flatDir dirs: "gradle/plugins"maven { url "https://maven.aliyun.com/repository/public" } // 阿里云鏡像maven { url "https://maven.aliyun.com/repository/gradle-plugin" } // 阿里云插件倉庫mavenCentral() // 保留官方倉庫作為 fallback google()}dependencies {classpath "com.android.tools.build:gradle:$android_plugin_version"classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'classpath 'com.vanniktech:gradle-maven-publish-plugin:0.25.2'}}allprojects {repositories {maven { url "https://maven.aliyun.com/repository/public" } // 阿里云鏡像maven { url "https://maven.aliyun.com/repository/gradle-plugin" } // 阿里云插件倉庫mavenCentral()google()}tasks.withType(Javadoc) {// Ignores errors from mavenAndroidJavadocs task// (reference: github.com/novoda/bintray-release/issues/71#issuecomment-164324255)options.addStringOption('Xdoclint:none', '-quiet')options.addStringOption('encoding', 'UTF-8')}}ext {libvlcVersion = '3.6.2'androidxLegacyVersion = '1.0.0'androidxAnnotationVersion = '1.7.1'}

使用(aar)播放.H264參考代碼

輸出文件: libvlcjni/libvlc/build/outputs/aar/libvlc-dev.aar

build.gradle

dependencies {implementation files("path-to-vlc-android/libvlcjni/libvlc/build/outputs/aar/libvlc-dev.aar");
}

h264_player.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><SurfaceView android:id="@+id/sv"android:layout_width="match_parent"android:layout_height="match_parent"/>
</RelativeLayout>

H264Player.java

import android.net.Uri;
import android.os.Bundle;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;import com.ansondroider.acore.BaseActivity;
import com.ansondroider.acore.Logger;
import com.nmbb.vlc.R;import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.MediaPlayer;
import org.videolan.libvlc.interfaces.IMedia;import java.util.ArrayList;public class H264Player extends BaseActivity {SurfaceView sv;String path = "/sdcard/test.h264";MediaPlayer vlcMp;LibVLC libVLC;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.h264_player);sv = (SurfaceView) findViewById(R.id.sv);sv.getHolder().addCallback(new SurfaceHolder.Callback() {@Overridepublic void surfaceCreated(SurfaceHolder surfaceHolder) {playH264();}@Overridepublic void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {}@Overridepublic void surfaceDestroyed(SurfaceHolder surfaceHolder) { }});if(!isPermissionReady(getRequiredPermissions()))getPermissions(getRequiredPermissions(), REQ_PERMS);}void playH264() {Logger.d(TAG, "playH264");if(libVLC == null) {// 初始化 LibVLC(可添加額外配置參數)ArrayList<String> options = new ArrayList<>();options.add("--no-drop-late-frames"); // 不丟棄延遲幀options.add("--no-skip-frames");      // 不跳過幀libVLC = new LibVLC(this, options);vlcMp = new MediaPlayer(libVLC);vlcMp.setEventListener(new MediaPlayer.EventListener() {@Overridepublic void onEvent(MediaPlayer.Event event) {Logger.d(TAG, "onEvent: " + event.type);switch (event.type) {case MediaPlayer.Event.EndReached:Logger.d(TAG, "播放結束");break;case MediaPlayer.Event.EncounteredError:Logger.e(TAG, "遇到錯誤:" + event.getRecordPath());break;}}});//設置顯示的控件vlcMp.getVLCVout().setVideoView(sv);vlcMp.getVLCVout().attachViews();}// 創建媒體對象并指定格式參數Media media = new Media(libVLC, Uri.parse("file://" + path));// 關鍵:強制指定為 H.264 格式和解復用器media.addOption(":input-format=h264"); // 輸入格式為 h264media.addOption(":demux=h264");       // 使用 h264 解復用器// 額外添加解碼器選項(強制使用FFmpeg解碼)//media.addOption(":codec=avcodec");media.setHWDecoderEnabled(true, false); // 啟用硬件解碼(可選)media.setEventListener(new Media.EventListener() {@Overridepublic void onEvent(Media.Event event) {Logger.d(TAG, "onEvent: " + event.type);if(event.type == Media.Event.MetaChanged){Logger.d(TAG, "媒體元數據改變");int trackCount = media.getTrackCount();for(int i = 0; i < trackCount; i++){IMedia.Track track = media.getTrack(i);if(track instanceof IMedia.VideoTrack){Logger.d(TAG, "視頻軌道:" + track.type);Logger.d(TAG, "Size: " + ((IMedia.VideoTrack) track).width + "x" + ((IMedia.VideoTrack) track).height);}}}}});// 設置媒體并播放vlcMp.setMedia(media);media.release(); // 釋放 media 對象vlcMp.play();}@Overrideprotected void onDestroy() {super.onDestroy();// 釋放資源vlcMp.stop();vlcMp.release();libVLC.release();}
}

參考

  1. vlc-android
  2. Ubuntu 16.04 Compile VLC for Android Failed

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/919956.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/919956.shtml
英文地址,請注明出處:http://en.pswp.cn/news/919956.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

并聯諧振與串聯諧振

在LC電路中&#xff0c;感抗和容抗相等時對應的頻率值稱為諧振頻率&#xff0c;在接收廣播電視信號或無線通信信號時&#xff0c;使接收電路的頻率與所選擇的發射的信號頻率相同就叫做調諧。并聯諧振LC并聯諧振電路是指將電感器和電容器并聯形成&#xff0c;如圖所示。在并聯諧…

打印機怎么連接電腦?打印機驅動?【圖文詳解】USB連接打印機?wifi連接打印機?

一、問題背景 在日常辦公與生活里&#xff0c;把電腦和打印機連接起來&#xff0c;是實現文檔、照片等打印的基礎操作。但很多人初次嘗試時&#xff0c;會因不熟悉流程而感到無從下手。 無論是辦公場景下急需打印重要文件&#xff0c;還是日常生活中想要打印照片留念&#xff0…

CVPR 2025 | 醫學影像加速進化:深度學習×多模態,精準診斷再升級

關注gongzhonghao【CVPR頂會精選】今天聊一個醫學圖像領域的前沿探索&#xff1a;結合空間感知卷積、擴散模型與視覺語言模型&#xff0c;從圖像配準到合成分割&#xff0c;再到跨模態理解&#xff0c;打造了一個更加智能、魯棒且可泛化的醫學影像工具鏈。無論是SACB-Net帶來的…

[每周一更]-(第157期):深入理解Go語言的垃圾回收機制:調優與監控

Go語言以其簡潔的語法和強大的并發能力而聞名&#xff0c;而它的垃圾回收&#xff08;GC&#xff09;機制則是支撐其高性能的關鍵組件之一。本文將深入探討Go語言的垃圾回收原理&#xff0c;并介紹如何對其進行調優與監控&#xff0c;以提升應用程序的性能。 Go語言垃圾回收機制…

Java 學習筆記(基礎篇9)

1. 綜合練習題目 1 &#xff1a;金額轉換為中文大寫格式請編寫一個 Java 程序&#xff0c;實現將數字金額轉換為中文大寫格式&#xff08;帶單位&#xff09;的功能&#xff0c;具體要求如下&#xff1a;(1) 程序接收用戶輸入的一個整數金額&#xff08;范圍&#xff1a;0-9999…

云原生俱樂部-k8s知識點歸納(5)

寫到這里&#xff0c;k8s的內容已經到一半了&#xff0c;雖然后面的內容我覺得更加玄學一點。控制器真的是個神奇的東西&#xff0c;雖然后面的CRD會帶著大家一起做一個控制器&#xff0c;但是還是覺得很奇妙。控制器大概就是k8s中的精華了&#xff0c;通過控制器去監聽k8s中ap…

C++復習2

C繼承 繼承的概念 繼承&#xff08;inheritance&#xff09;機制是面向對象程序設計使代碼可以復用的重要的手段&#xff0c;它允許程序員在保持原有類特性的基礎上進行擴展&#xff0c;增加功能&#xff0c;這樣產生新的類&#xff0c;稱為派生類。 繼承呈現了面向對象程序設計…

ZKmall模塊商城的跨境電商支付安全方案:加密與權限的雙重防護

跨境電商支付環節面臨雙重挑戰&#xff1a;一方面&#xff0c;不同國家的支付協議、貨幣結算規則差異顯著&#xff0c;需滿足多幣種、多渠道的支付需求&#xff1b;另一方面&#xff0c;跨境數據傳輸的安全性與操作權限的嚴格管控直接關系到資金安全與合規性。ZKmall 模塊商城針…

【數據結構】-5- 順序表 (下)

一、集合框架 這是 Java 集合框架&#xff08;Java Collections Framework&#xff09;的核心繼承關系樹狀圖1. 最頂層&#xff1a;Iterable&#xff08;接口&#xff09;作用&#xff1a;所有 “可迭代” 的集合&#xff08;如 List、Set、Queue&#xff09;都必須實現它&…

最大連續1的個數Ⅲ-滑動窗口

1004. 最大連續1的個數 III - 力扣&#xff08;LeetCode&#xff09; Solution 標準滑動窗口。 class Solution { public:int longestOnes(vector<int>& nums, int k) {int nnums.size();int l0,z_cnt0,ans0;for(int r0;r<n;r){z_cnt1-nums[r];while(z_cnt>k…

實驗二 Cisco IOS Site-to-Site Pre-share Key

一 實驗設備 1、 CISCO 路由器 2 臺 二 實驗拓撲圖 三 實驗配置 1、 R1 路由器上連通性配置 R1(config)#interface e0/0 R1(config-if)#ip address 192.168.1.2 255.255.255.0 R1(config-if)#no shutdown R1(config)#interface e1/0 R1(config-if)#ip address 10.1.20.1 255.25…

深入理解 Rust Axum:兩種依賴注入模式的實踐與對比(二)

前言 我想把使用 Rust 開發Websocket 服務的文章寫成一個系列&#xff0c;前面寫了一遍如何使用 Axum 搭建一個Websocket 服務的文章&#xff0c;我們可以和前端demo頁面進行全雙工的 Websocket 消息傳輸&#xff0c;而且可以啟用 HTTP2 的同時啟用 TLS。 這時候問題來了&…

syn與quote的使用——結構體轉create語句

前言 syn和quote的簡單使用——生成結構體-CSDN博客https://blog.csdn.net/qq_63401240/article/details/150609865?spm1001.2014.3001.5501 前面使用syn和quote&#xff0c;發現挺好玩的&#xff0c;感覺可以干很多事情&#xff0c;不愧是Rust中的宏。 宏分為聲明宏和過程…

集中式負載均衡 vs. 分布式負載均衡

集中式負載均衡 vs. 分布式負載均衡負載均衡&#xff08;Load Balancing&#xff09;是任何可伸縮系統的“交通警察”。 集中式負載均衡&#xff08;Centralized LB&#xff09;與分布式負載均衡&#xff08;Distributed LB&#xff09;代表了兩種截然不同的“指揮哲學”&#…

【機器學習】9 Generalized linear models and the exponential family

本章目錄 9 Generalized linear models and the exponential family 281 9.1 Introduction 281 9.2 The exponential family 281 9.2.1 Definition 282 9.2.2 Examples 282 9.2.3 Log partition function 284 9.2.4 MLE for the exponential family 286 9.2.5 Bayes for the e…

EndNote 2025 Mac 文獻管理工具

原文地址&#xff1a;EndNote 2025 Mac 文獻管理工具 EndNote mac版一款文獻管理工具&#xff0c;支持國際期刊的參考文獻格式有3776種&#xff0c;寫作模板幾百種&#xff0c;涵蓋各個領域的雜志。 EndNote mac不僅僅局限于投稿論文的寫作&#xff0c;對于研究生畢業論文的寫…

openEuler系統中home文件夾下huawei、HwHiAiUser、lost+found 文件夾的區別和作用

在 openEuler 系統的 /home 目錄下出現的 huawei、HwHiAiUser 和 lost+found 文件夾,分別對應不同的功能和用途,具體區別和作用如下: 1. lost+found 文件夾 通用 Linux 系統文件夾:lost+found 是所有 Linux 系統(包括 openEuler)中默認存在的文件夾,并非 openEuler 特有…

Electron 核心 API 全解析:從基礎到實戰場景

Electron 憑借豐富的 API 體系&#xff0c;讓前端開發者能輕松調用系統級能力。本文將系統梳理 Electron 核心 API 的分類、使用場景及實戰示例&#xff0c;幫你快速掌握從窗口管理到進程通信的全場景開發。 一、主進程核心 API&#xff08;Main Process&#xff09; 主進程是…

創建線程的方式有哪些?

1. 創建線程的方式有哪些?繼承Thread類實現runnable接口實現Callable接口線程池創建線程(項目中使用方式)2. runnable 和 callable 有什么區別?Runnable接口run方法沒有返回值Callable接口call方法有返回值,需要FutureTask獲取結果Callable接口的call()方法允許拋出異常;而Ru…

More Effective C++ 條款05: 謹慎定義類型轉換函數

More Effective C 條款05&#xff1a;謹慎定義類型轉換函數核心思想&#xff1a;C中的隱式類型轉換雖然方便&#xff0c;但容易導致意外的行為和維護難題。應當通過explicit關鍵字和命名轉換函數等方式嚴格控制類型轉換&#xff0c;優先使用顯式轉換而非隱式轉換。 &#x1f68…