当前位置: 首页 > news >正文

Android开启HTTP服务

需求:通过手机给设备升级固件,设备有WIFI

方案:升级包放到APP可以访问的目录,手机开热点并启动一个HTTP服务,设备连接手机热点,另外,设备端开启一个 telnet 服务,手机通过 telnet 登录到设备系统(Android系统热点的默认IP地址是192.168.43.1,APP可以遍历192.168.43这个IP段的IP以及固定的端口),通过指令下载固件,完成升级。

1. 用到的第三方库

implementation 'commons-net:commons-net:3.9.0' // telnet
implementation 'org.nanohttpd:nanohttpd:2.3.1' // NanoHttpd
implementation 'org.apache.commons:commons-compress:1.23.0'//解压缩文件
implementation 'com.github.junrar:junrar:7.5.4'//解压rar
implementation 'org.tukaani:xz:1.9'//解压.7z文件需要
implementation 'com.sparkjava:spark-core:2.9.4'// sparkjava

2. 添加权限

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /><uses-permission android:name="android.permission.WRITE_SETTINGS" /><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><!-- If your app targets Android 13 (API level 33)or higher, you must declare the NEARBY_WIFI_DEVICES permission. --><!-- If your app derives location information fromWi-Fi APIs, don't include the "usesPermissionFlags"attribute. --><uses-permissionandroid:name="android.permission.NEARBY_WIFI_DEVICES"android:usesPermissionFlags="neverForLocation"tools:targetApi="s" /><!-- If any feature in your app relies onprecise location information, don't include the"maxSdkVersion" attribute. --><!--  Android12获取SSID需要 ACCESS_FINE_LOCATION 权限  --><uses-permissionandroid:name="android.permission.ACCESS_FINE_LOCATION"android:maxSdkVersion="32" /><uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"android:maxSdkVersion="32" />

3. 开启热点 

APUtil.kt

import android.Manifest
import android.content.ActivityNotFoundException
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.wifi.SoftApConfiguration
import android.net.wifi.WifiManager
import android.os.Build
import android.util.Log
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import java.lang.reflect.Field
import java.lang.reflect.Methodclass APUtil(private val context: Context) {val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManagerprivate fun securityTypeString(securityType: Int): String {return when (securityType) {SoftApConfiguration.SECURITY_TYPE_OPEN -> "OPEN"SoftApConfiguration.SECURITY_TYPE_WPA2_PSK -> "WPA2_PSK"SoftApConfiguration.SECURITY_TYPE_WPA3_OWE -> "WPA3_OWE"SoftApConfiguration.SECURITY_TYPE_WPA3_SAE -> "WPA3_SAE"SoftApConfiguration.SECURITY_TYPE_WPA3_OWE_TRANSITION -> "WPA3_OWE_TRANSITION"SoftApConfiguration.SECURITY_TYPE_WPA3_SAE_TRANSITION -> "WPA3_SAE_TRANSITION"else -> "Unknown security type: $securityType"}}@RequiresApi(Build.VERSION_CODES.O)private val localOnlyHotspotCallback = object : WifiManager.LocalOnlyHotspotCallback() {override fun onStarted(reservation: WifiManager.LocalOnlyHotspotReservation?) {super.onStarted(reservation)if (Build.VERSION.SDK_INT >= 30) {reservation?.softApConfiguration?.let { config ->Log.i(TAG, "-------------------------- softApConfiguration --------------------------")if (Build.VERSION.SDK_INT >= 33) {Log.i(TAG, "热点名称: ${config.wifiSsid}")} else {Log.i(TAG, "热点名称: ${config.ssid}")}Log.i(TAG, "热点密码: ${config.passphrase}")Log.i(TAG, "securityType=${securityTypeString(config.securityType)}")Log.i(TAG, "mac=${config.bssid}")}} else {reservation?.wifiConfiguration?.let { config ->Log.i(TAG, "-------------------------- wifiConfiguration --------------------------")Log.i(TAG, "热点名称: ${config.SSID}")Log.i(TAG, "热点密码: ${config.preSharedKey}")Log.i(TAG, "mac=${config.BSSID}")Log.i(TAG, "status=${config.status}")config.httpProxy?.let { httpProxy ->Log.i(TAG, "http://${httpProxy.host}:${httpProxy.port}")}}}}override fun onStopped() {super.onStopped()Log.e(TAG, "onStopped()")}override fun onFailed(reason: Int) {super.onFailed(reason)Log.e(TAG, "onFailed() - reason=$reason")}}fun startHotspot() {if (Build.VERSION.SDK_INT >= 26) {if (ActivityCompat.checkSelfPermission(context,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(context,Manifest.permission.NEARBY_WIFI_DEVICES) != PackageManager.PERMISSION_GRANTED) {return}// 官方文档// https://developer.android.google.cn/reference/android/net/wifi/WifiManager#startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback,%20android.os.Handler)wifiManager.startLocalOnlyHotspot(localOnlyHotspotCallback, null)}}fun printHotSpotState() {Log.i(TAG, "热点是否已经打开:方式1 ${isHotSpotApOpen(context)} 方式2 ${isHotSpotApOpen2(context)}")Log.i(TAG, "手机型号:${Build.MANUFACTURER} ${Build.MODEL}")}companion object {private const val TAG = "APUtil"//获取热点是否打开方式1fun isHotSpotApOpen(context: Context): Boolean {var isAPEnable = falsetry {val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManagerval method: Method = wifiManager.javaClass.getDeclaredMethod("getWifiApState")val state = method.invoke(wifiManager) as Intval field: Field = wifiManager.javaClass.getDeclaredField("WIFI_AP_STATE_ENABLED")val value = field.get(wifiManager) as IntisAPEnable = state == valueLog.i(TAG, "state=$state, value=$value")} catch (e: Exception) {e.printStackTrace()}return isAPEnable}//获取热点是否打开方式2fun isHotSpotApOpen2(context: Context): Boolean {var isAPEnable = falsetry {val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManagerval method: Method = wifiManager.javaClass.getDeclaredMethod("isWifiApEnabled")method.isAccessible = trueisAPEnable = method.invoke(wifiManager) as Boolean} catch (e: Exception) {e.printStackTrace()}return isAPEnable}/*** 打开设置热点的页面*/fun openSettings(context: Context) {val intent = Intent()intent.addCategory(Intent.CATEGORY_DEFAULT)intent.action = "android.intent.action.MAIN"val cn = ComponentName("com.android.settings","com.android.settings.Settings\$WirelessSettingsActivity")intent.component = cntry {context.startActivity(intent)} catch (ex: ActivityNotFoundException) {intent.component = ComponentName("com.android.settings","com.android.settings.Settings\$TetherSettingsActivity")context.startActivity(intent)}}}
}

4. 开启HTTP服务

使用 nanohttpd 实现

 HttpFileServer.kt

import android.content.Context
import android.util.Log
import fi.iki.elonen.NanoHTTPD
import org.json.JSONObject
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.IOException
import java.util.stream.Collectors/*** 手机开热点时使用的IP*/
const val SERVER_IP = "192.168.43.1"
const val SERVER_PORT = 8080private const val TAG = "HttpFileServer"// HFS
class HttpFileServer(context: Context, ipAddress: String) : NanoHTTPD(ipAddress, SERVER_PORT) {init {rootDir = context.getExternalFilesDir("OTA")!!.absolutePathLog.i(TAG, "rootDir=$rootDir")}override fun serve(session: IHTTPSession): Response? {val params = session.parametersLog.e(TAG, String.format("uri=%s", session.uri))for (entry in params.entries) {Log.e(TAG, String.format("%s=%s", entry.key, entry.value.stream().collect(Collectors.joining(", "))))}return responseFile(session)}private fun responseFile(session: IHTTPSession): Response? {//目前使用的是 http://192.168.43.1:8080/filenameval uri = session.urival filename = uri.substring(uri.lastIndexOf('/') + 1)return try {//文件输入流val fis = FileInputStream("$rootDir/${filename}")newFixedLengthResponse(Response.Status.OK, "application/octet-stream", fis, fis.available().toLong())} catch (e: FileNotFoundException) {Log.e(TAG, "$filename 文件不存在!", e)val jsonObj = JSONObject()jsonObj.put("message", "$filename 文件不存在!")Log.e(TAG, jsonObj.toString(2))newFixedLengthResponse(Response.Status.NOT_FOUND, "application/json", jsonObj.toString(2))} catch (e: IOException) {e.printStackTrace()newFixedLengthResponse(session.uri + " 异常 " + e)}}companion object {var rootDir: String = ""}
}

使用 sparkjava 实现 

 注意:使用的是sparkjava,而不是大数据分析的那个Spark!

// http://192.168.43.1:8080/download?filename=dog.jpg
Spark.port(8080)        
Spark.get("download") { req, res ->val filename = req.queryParams("filename")println("thread ${Thread.currentThread().id} - $filename")res.status(200)res.header("Content-Type", "application/octet-stream")res.header("Content-disposition", "attachment; filename=$filename")context.assets.open(filename).use { istream ->istream.copyTo(res.raw().outputStream)}res
}

5. 使用 telnet

WifiUtil.kt

telnet 主要用到了 WifiUtil 的一个属性:network

import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.net.wifi.WifiNetworkSpecifier
import android.os.Build
import android.os.PatternMatcher
import android.util.Log
import androidx.annotation.RequiresApi
import site.feiyuliuxing.wifitest.toIPAddressclass WifiUtil(context: Context) {private val mNetworkCallback: ConnectivityManager.NetworkCallbackprivate val mConnectivityManager: ConnectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManagerprivate val wifiManager: WifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManagerprivate var mNetwork: Network? = null//Android系统热点的默认IP地址是192.168.43.1var hostIP = "192.168.43.1"private setval network: Network?get() = mNetworkval targetIP: Stringget() {val arr = hostIP.split(".").toMutableList()arr[arr.lastIndex] = "1"return arr.joinToString(".")}init {if (Build.VERSION.SDK_INT < 29) {//Android10以下系统mNetworkCallback = object : ConnectivityManager.NetworkCallback() {override fun onAvailable(network: Network) {callbackAvailable(network)}override fun onLost(network: Network) {callbackLost(network)}}} else if (Build.VERSION.SDK_INT < 31) {//Android10 Android11mNetworkCallback = object : ConnectivityManager.NetworkCallback() {override fun onAvailable(network: Network) {callbackAvailable(network)}override fun onLost(network: Network) {callbackLost(network)}@RequiresApi(Build.VERSION_CODES.Q)override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {// Android10才支持该回调方法callbackCapabilitiesChanged(network, networkCapabilities)}}} else {//Android12获取 SSID 需要 FLAG_INCLUDE_LOCATION_INFO 并获得 ACCESS_FINE_LOCATION 权限mNetworkCallback = object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {override fun onAvailable(network: Network) {callbackAvailable(network)}override fun onLost(network: Network) {callbackLost(network)}@RequiresApi(Build.VERSION_CODES.Q)override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {// Android10才支持该回调方法callbackCapabilitiesChanged(network, networkCapabilities)}}}}private fun callbackAvailable(network: Network) {mNetwork = networkhostIP = getIP(network)}private fun callbackLost(network: Network) {mNetwork = null}@RequiresApi(Build.VERSION_CODES.Q)private fun callbackCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {val wifiInfo = networkCapabilities.transportInfo as WifiInfo?if (wifiInfo != null) {println("onCapabilitiesChanged() - SSID=${wifiInfo.ssid}, IP=${wifiInfo.ipAddress.toIP()}")}}private val networkRequest: NetworkRequestget() = NetworkRequest.Builder().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).apply {if (Build.VERSION.SDK_INT >= 29) {val wifiNetworkSpecifier = WifiNetworkSpecifier.Builder()
//                        .setBand(ScanResult.WIFI_BAND_24_GHZ)//Android12 但是设置这个参数后无法连接.setSsidPattern(PatternMatcher("ZS[0-9a-fA-F]{8}", PatternMatcher.PATTERN_ADVANCED_GLOB))
//                        .setSsid("ZS3755a0e2").setWpa2Passphrase("12345678").build()setNetworkSpecifier(wifiNetworkSpecifier)}}.build()fun requestConnectWIFI() {mConnectivityManager.requestNetwork(networkRequest, mNetworkCallback)}fun close() {mConnectivityManager.unregisterNetworkCallback(mNetworkCallback)}//无需运行时申请权限fun getGatewayIP(): String {if (Build.VERSION.SDK_INT < 32) {/*This method was deprecated in API level 31.Use the methods on LinkProperties which can be obtained either viaNetworkCallback#onLinkPropertiesChanged(Network, LinkProperties) orConnectivityManager#getLinkProperties(Network).*/val dhcpInfo = wifiManager.dhcpInfo// 网关IP地址是一个整数,需要转换为可读的IP地址格式val gatewayIpAddress: String = dhcpInfo.gateway.toIPAddress()println("Gateway IP: $gatewayIpAddress")return gatewayIpAddress} else {var addr = ""mConnectivityManager.activeNetwork?.let { network ->mConnectivityManager.getLinkProperties(network)?.let { linkProperties ->linkProperties.dhcpServerAddress?.let { inet4Address ->addr = inet4Address.hostAddress ?: ""}}}println("网关IP: $addr")return addr}}private fun getIP(network: Network): String {mConnectivityManager.getLinkProperties(network)?.linkAddresses?.let { linkAddresses ->linkAddresses.forEach { linkAddress ->// hostAddress: the IP address string in textual presentation.linkAddress.address.hostAddress?.let { hostAddress ->if (hostAddress.isValidIP) {println("手机IP:${hostAddress}")return hostAddress}}}}return ""}private val ipRegex = """\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}""".toRegex()private val String.isValidIP: Booleanget() = ipRegex.matches(this)private fun Int.toIP(): String {return "${this.and(0xff)}" +".${this.shr(8).and(0xff)}" +".${this.shr(16).and(0xff)}" +".${this.shr(24).and(0xff)}"}
}

TelnetUtil.kt

import android.net.Network
import org.apache.commons.net.telnet.EchoOptionHandler
import org.apache.commons.net.telnet.SuppressGAOptionHandler
import org.apache.commons.net.telnet.TelnetClient
import org.apache.commons.net.telnet.TerminalTypeOptionHandlerclass TelnetUtil {private val telnetClient = TelnetClient()private fun connectServer(ip: String, network: Network?): Boolean {try {if (network != null) {telnetClient.setSocketFactory(network.socketFactory)}/*val ttopt = TerminalTypeOptionHandler("VT220", false, false, true, false)val echoopt = EchoOptionHandler(true, false, true, false)val gaopt = SuppressGAOptionHandler(true, true, true, true)telnetClient.addOptionHandler(ttopt)telnetClient.addOptionHandler(echoopt)telnetClient.addOptionHandler(gaopt)*/telnetClient.connect(ip, 23)if (telnetClient.isConnected) {println("端口可用 $ip")return true}} catch (ex: Exception) {ex.printStackTrace()}return false}fun readUntil(match: String, timeout: Long = 10_000): Boolean {val sb = StringBuilder()val startTime = System.currentTimeMillis()while (true) {if ((System.currentTimeMillis() - startTime) >= timeout) {//超时break}var len = telnetClient.inputStream.available()while (len > 0) {val ch = telnetClient.inputStream.read()if (ch != -1) {sb.append(ch.toChar())print(ch.toChar())if (ch == 0x0D || ch == 0x0A) {System.out.flush()}if (sb.contains(match)) {println(sb.toString())return true}}len--}}println(sb.toString())return false}fun send(msg: String) {telnetClient.outputStream.apply {write(msg.toByteArray(Charsets.UTF_8))flush()}}
}

6. 解压缩文件

参考这篇文章:Android解压 zip rar 7z 文件

相关文章:

Android开启HTTP服务

需求&#xff1a;通过手机给设备升级固件&#xff0c;设备有WIFI 方案&#xff1a;升级包放到APP可以访问的目录&#xff0c;手机开热点并启动一个HTTP服务&#xff0c;设备连接手机热点&#xff0c;另外&#xff0c;设备端开启一个 telnet 服务&#xff0c;手机通过 telnet 登…...

NLP - word2vec详解

Word2Vec是一种用于将词汇映射到高维向量空间的自然语言处理技术。由Google在2013年提出&#xff0c;它利用浅层神经网络模型来学习词汇的分布式表示。Word2Vec有两种主要模型&#xff1a;CBOW&#xff08;Continuous Bag of Words&#xff09;和Skip-gram。 1. 模型介绍 Con…...

AI办公自动化:用通义千问批量翻译长篇英语TXT文档

在deepseek中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;现在要完成一个编写基于qwen-turbo模型API和dashscope库的程序脚本&#xff0c;具体步骤如下&#xff1a; 打开文件夹&#xff1a;F:\AI自媒体内容\待翻译&#xff1b; 获取里面所有TXT文档&#xff…...

一键解压,无限可能——BetterZip,您的Mac必备神器!

BetterZip for Mac 是一款高效、智能且安全的解压缩软件&#xff0c;专为Mac用户设计。它提供了直观易用的界面&#xff0c;使用户能够轻松应对各种压缩和解压缩需求。 这款软件不仅支持多种压缩格式&#xff0c;如ZIP、RAR、7Z等&#xff0c;还具备快速解压和压缩文件的能力。…...

【数学】什么是最大似然估计?如何求解最大似然估计

背景 最大似然估计&#xff08;Maximum Likelihood Estimation, MLE&#xff09;是一种估计统计模型参数的方法。它在众多统计学领域中被广泛使用&#xff0c;比如回归分析、时间序列分析、机器学习和经济学。其核心思想是&#xff1a;给定一个观测数据集&#xff0c;找到一组…...

跟张良均老师学大数据人工智能|企业项目试岗实训开营

我国高校毕业生数量连年快速增长&#xff0c;从2021年的909万人到2022年的1076万人&#xff0c;再到2023年的1158万人&#xff0c;预计到2024年将达到1187万人&#xff0c;2024年高校毕业生数量再创新高。 当年高校毕业生人数不等于进入劳动力市场的高校毕业生人数&#x…...

Pentest Muse:一款专为网络安全人员设计的AI助手

关于Pentest Muse Pentest Muse是一款专为网络安全研究人员和渗透测试人员设计和开发的人工智能AI助手&#xff0c;该工具可以帮助渗透测试人员进行头脑风暴、编写Payload、分析代码或执行网络侦查任务。除此之外&#xff0c;Pentest Muse甚至还能够执行命令行代码并以迭代方式…...

10 SpringBoot 静态资源访问

我们在开发Web项目的时候&#xff0c;往往会有很多静态资源&#xff0c;如html、图片、css等。那如何向前端返回静态资源呢&#xff1f; 以前做过web开发的同学应该知道&#xff0c;我们以前创建的web工程下面会有一个webapp的目录&#xff0c;我们只要把静态资源放在该目录下…...

Unity 之通过自定义协议从浏览器启动本地应用程序

内容将会持续更新&#xff0c;有错误的地方欢迎指正&#xff0c;谢谢! Unity 之通过自定义协议从浏览器启动本地应用程序 TechX 坚持将创新的科技带给世界&#xff01; 拥有更好的学习体验 —— 不断努力&#xff0c;不断进步&#xff0c;不断探索 TechX —— 心探索、心进…...

Python抓取天气信息

Python的详细学习还是需要些时间的。如果有其他语言经验的&#xff0c;可以暂时跟着我来写一个简单的例子。 2024年最新python教程全套&#xff0c;学完即可进大厂&#xff01;&#xff08;附全套视频 下载&#xff09; (qq.com) 我们计划抓取的数据&#xff1a;杭州的天气信息…...

【超越拟合:深度学习中的过拟合与欠拟合应对策略】

如何处理过拟合 由于过拟合的主要问题是你的模型与训练数据拟合得太好&#xff0c;因此你需要使用技术来“控制它”。防止过拟合的常用技术称为正则化。我喜欢将其视为“使我们的模型更加规则”&#xff0c;例如能够拟合更多类型的数据。 让我们讨论一些防止过拟合的方法。 获…...

【Orange Pi 5与Linux内核编程】-理解Linux内核中的container_of宏

理解Linux内核中的container_of宏 文章目录 理解Linux内核中的container_of宏1、了解C语言中的struct内存表示2、Linux内核的container_of宏实现理解3、Linux内核的container_of使用 Linux 内核包含一个名为 container_of 的非常有用的宏。本文介绍了解 Linux 内核中的 contain…...

003.Linux SSH协议工具

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…...

web前端组织分析:深入剖析其结构、功能与未来趋势

web前端组织分析&#xff1a;深入剖析其结构、功能与未来趋势 在数字化浪潮的推动下&#xff0c;Web前端组织作为连接用户与数字世界的桥梁&#xff0c;其重要性日益凸显。本文将从四个方面、五个方面、六个方面和七个方面对Web前端组织进行深入分析&#xff0c;揭示其结构特点…...

GitCode热门开源项目推荐:Spider网络爬虫框架

在数字化高速发展时代&#xff0c;数据已成为企业决策和个人研究的重要资源。网络爬虫作为一种强大的数据采集工具受到了广泛的关注和应用。在GitCode这一优秀的开源平台上&#xff0c;Spider网络爬虫框架凭借其简洁、高效和易用性&#xff0c;成为了众多开发者的首选。 一、系…...

实现一个二叉树的前序遍历、中序遍历和后序遍历方法。

package test3;public class Test_A27 {// 前序遍历&#xff08;根-左-右&#xff09;public void preOrderTraversal(TreeNode root){if(rootnull){return;}System.out.println(root.val"");preOrderTraversal(root.left);preOrderTraversal(root.right);}// 中序遍…...

串扰(二)

三、感性串扰 首先看下串扰模型及电流方向&#xff1a; 由于电感是阻碍电流变化&#xff0c;受害线的电流方向和攻击线的电流方向相反。同时由于受害线阻抗均匀&#xff0c;故有Vb-Vf&#xff08;感应电流属于电池内部电流&#xff09;。 分析感性串扰大小仍然是按微分的方法…...

零基础入门学用Arduino 第四部分(三)

重要的内容写在前面&#xff1a; 该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。个人把这个教程学完之后&#xff0c;整体感觉是很好的&#xff0c;如果有条件的可以先学习一些相关课程&#xff0c;学起来会更加轻松&#xff0c;相关课程有数字电路…...

Mp3文件结构全解析(一)

Mp3文件结构全解析(一) MP3 文件是由帧(frame)构成的&#xff0c;帧是MP3 文件最小的组成单位。MP3的全称应为MPEG1 Layer-3 音频 文件&#xff0c;MPEG(Moving Picture Experts Group) 在汉语中译为活动图像专家组&#xff0c;特指活动影音压缩标准&#xff0c;MPEG 音频文件…...

ES 8.14 Java 代码调用,增加knnSearch 和 混合检索 mixSearch

1、pom依赖 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>8.14.0</version></dependency><dependency><groupId>co.elastic.clients<…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...