在这里插入图片描述

概述

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…