文本转语音-音画适时推送rtsp并播放
文本语音 rtsp适时播放叫号系统的底层逻辑
发布Linux, unix socket 和window win32做为音频源的 python10下的(ffmpeg version 7.1) 可运行版本.
这两天在弄这个,前2篇是通过虚拟声卡,达到了最简单的一个逻辑,播放文本就从声卡发声,不播无所谓,自动忙音。 那个工作在windows平台,
而今天的这个相似功能的代码是mac os,理论支持windows,和linux,依赖ffmpeg和xiu(一个rust流服务器)的rtsp服务。
今天的难点有点多
- asyncio的任务 async def _tts_worker(self, text: str) 运行中有各种错误, engine runAndWait是不行的。 内部有它的event loop。所以init和endLoop,是暂时找到的解决办法。同时经历了,这个,和调用 ffmpeg 外部指令,并直接获取- 代表的stdout。 会遇到各种问题。做了捕获和处理。但是查找的时候,不是太容易。
- self._start_ffmpeg() 他需要, create socket 或pipe完成以后,才能运行。 调试我都手工在外部启动。 作用就是,输出到rtsp服务器,以备播放。
- input handle,等都是ai生成的,因为有好多种循环,这是比较省心在。
- 最紧急隐蔽在是, async def _heartbeat(self) 他需要计算播放静音的时间,长了不行,短了不行。 这个最初在测试代码,就几个函数。然后AI,生成了三个theading的版本,两个Queue。 然后转到了异步版本,明显快了很多。
- 在windows上使用win32pipen可以达到unix socket的效果很相似, 记得还有FIFO是linux专用的,当然还有stdin,和stdout。对于ffmpeg,这是一些程序内部的传送机制
- rtsp是需要一个后台的服务的,xiu是开源的rust项目,可以使。另外window推荐metamtx,双击运行,什么也不管。
音画同步应该是另个问题了,几天前,鼓捣了一下图片。让编辑后的,马上 在视频中显示。 这个另外一个话题了。做的这些就为了,让报号和点单,有个界面。
ffmpeg -re -framerate 30 -f image2 -loop 1 -i "image1.jpg" -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt rgba -f rtsp -rtsp_transport tcp rtsp://localhost:8554/live
合并的代码,就当成剩下的作业,有空再来做。
对于刚接触的,最好是慢慢和AI调试着来,一些功能就做出来。
语音推送使用ffmpeg独立进程,实现了前后中断后自动重启。
程序主体
可独立运行,也可以结合ffmg管理推送进程
- macos ,理论Linux适用,单文件可执行
main.py
import asyncio
import struct
import pyttsx3
import tempfile
import os
import socket
from aioconsole import ainput
from contextlib import suppress
from typing import Optionalclass AsyncTTSController:def __init__(self):# 使用Unix域套接字self.socket_path = "/tmp/tts_audio.sock"self.server_socket: Optional[socket.socket] = Noneself.client_socket: Optional[socket.socket] = None# 进程控制self.ffmpeg_process: Optional[asyncio.subprocess.Process] = Noneself.running = False# TTS引擎self.engine = pyttsx3.init()self.engine.setProperty('rate', 180)self.engine.setProperty('volume', 1.0)# 音频参数self.sample_rate = 24000self.channels = 1self.bits_per_sample = 16self.silence = self._generate_silence(0.2)self.wav_header = self._generate_wav_header()# 状态管理self.connection_active = Falseself.last_heartbeat = 0.0self.heartbeat_interval = 2.0self.sending_audio = 0def _generate_wav_header(self) -> bytes:"""生成WAV文件头"""byte_rate = self.sample_rate * self.channels * self.bits_per_sample // 8block_align = self.channels * self.bits_per_sample // 8return struct.pack('<4sI4s4sIHHIIHH4sI',b'RIFF', 36, b'WAVE', b'fmt ', 16, 1, self.channels,self.sample_rate, byte_rate, block_align, self.bits_per_sample,b'data', 0)def _generate_silence(self, duration: float) -> bytes:"""生成静音数据"""samples = int(self.sample_rate * duration)return bytes(samples * self.channels * (self.bits_per_sample // 8))async def _async_create_socket(self) -> None:"""创建Unix域套接字"""with suppress(Exception):if os.path.exists(self.socket_path):os.unlink(self.socket_path)self.server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)self.server_socket.setblocking(False)self.server_socket.bind(self.socket_path)self.server_socket.listen(1)loop = asyncio.get_running_loop()while self.running and not self.connection_active:try:self.client_socket, _ = await loop.sock_accept(self.server_socket)self.connection_active = Trueprint("客户端已连接")await loop.sock_sendall(self.client_socket, self.wav_header)except (BlockingIOError, InterruptedError):await asyncio.sleep(0.1)except Exception as e:print(f"连接错误: {str(e)}")self.connection_active = Falseawait asyncio.sleep(1)async def _start_ffmpeg(self) -> None:"""启动FFmpeg进程"""with suppress(Exception):if self.ffmpeg_process:self.ffmpeg_process.terminate()await self.ffmpeg_process.wait()socketid='unix:'+self.socket_pathself.ffmpeg_process = await asyncio.create_subprocess_exec('ffmpeg','-f', 's16le','-ar', str(self.sample_rate),'-ac', str(self.channels),'-i', socketid, # 修改输入源为套接字路径'-c:a', 'aac','-f', 'rtsp','-rtsp_transport', 'tcp','rtsp://localhost:8554/mystream',stdout=asyncio.subprocess.DEVNULL,stdin=asyncio.subprocess.DEVNULL,stderr=asyncio.subprocess.PIPE)asyncio.create_task(self._monitor_ffmpeg_errors())async def _monitor_ffmpeg_errors(self) -> None:"""监控FFmpeg错误输出"""while self.running and self.ffmpeg_process:line = await self.ffmpeg_process.stderr.readline()if not line:break# print(f"[FFmpeg Error] {line.decode().strip()}")async def _async_write_socket(self, data: bytes) -> None:"""安全写入套接字"""try:if self.client_socket and self.connection_active:loop = asyncio.get_running_loop()await loop.sock_sendall(self.client_socket, data)except (BrokenPipeError, ConnectionResetError):print("连接已断开,尝试重连...")await self._reconnect_pipeline()except Exception as e:print(f"写入错误: {str(e)}")self.connection_active = Falseasync def _reconnect_pipeline(self) -> None:"""完整重连流程"""print("启动重连流程...")self.connection_active = Falseif self.client_socket:self.client_socket.close()task1=asyncio.create_task(self._async_create_socket()),task2=asyncio.create_task( self._start_ffmpeg()), await task2await task1# await asyncio.gather(task1, task2)#await self._async_create_socket()#await self._start_ffmpeg()# 剩余的heartbeat、tts_worker、input_handler等方法保持相同...async def stop(self) -> None:"""安全关闭"""self.running = Falsewith suppress(Exception):if self.ffmpeg_process:self.ffmpeg_process.terminate()await self.ffmpeg_process.wait()if self.client_socket:self.client_socket.close()if self.server_socket:self.server_socket.close()if os.path.exists(self.socket_path):os.unlink(self.socket_path)print("所有资源已释放")async def _heartbeat(self) -> None:"""心跳维持机制"""while self.running:if self.connection_active :for i in range(10):if self.sending_audio<0:await self._async_write_socket(self.silence)else :self.sending_audio-= 2await asyncio.sleep(0.2) # print(self.sending_audio,"slend")# await asyncio.sleep(self.heartbeat_interval)else:await asyncio.sleep(0.5)def _sync_tts(self,text,tmp_filename):eng=pyttsx3.init()# eng.say(text)eng.save_to_file(text, 'temp3.wav')eng.runAndWait()eng.endLoop()async def _tts_worker(self, text: str) -> None:"""异步TTS处理核心"""tmp_filename = None#with open('audio1.raw','rb') as chunkf:# data=chunkf.read()# secdd=len(data)/48000# self.sending_audio=int(secdd*10) # await self._async_write_socket(data)# #await asyncio.sleep(secdd)# print (secdd,len(data) ) # 创建临时文件with tempfile.NamedTemporaryFile(delete=False) as tmp:tmp_filename = tmp.name# # 同步TTS操作转异步执行loop = asyncio.get_running_loop()await loop.run_in_executor(None, self._sync_tts, *(text, 'temp3.wav',))# 转换音频格式# await asyncio.sleep(1.3)# self._sync_tts(text,tmp_filename)try: proc = await asyncio.create_subprocess_exec('ffmpeg','-hide_banner','-loglevel', 'error','-y','-i', 'temp3.wav', # 输入文件路径'-f', 's16le', # 强制输出格式为PCM s16le'-acodec', 'pcm_s16le', # 明确指定音频编解码器 👈 关键修复'-ar', str(self.sample_rate),'-ac', str(self.channels),'-', # 输出到标准输出stdout=asyncio.subprocess.PIPE
)# 流式发送音频数据sum=0while chunk := await proc.stdout.read(4096):sum+=len(chunk)await self._async_write_socket(chunk)self.sending_audio=int(sum*10/48000) print("write data x0.1s:",self.sending_audio)finally:if tmp_filename and os.path.exists(tmp_filename):1# os.unlink(tmp_filename)async def _input_handler(self) -> None:"""异步输入处理"""while self.running:try:text = await ainput("请输入文本(输入q退出): ")if text.lower() == 'q':self.running = Falsebreakif text.strip():await self._tts_worker(text)except Exception as e:print(f"输入错误: {str(e)}")async def run(self) -> None:"""主运行循环"""self.running = True# #await self._start_ffmpeg()tasks = [asyncio.create_task(self._async_create_socket()),asyncio.create_task( self._start_ffmpeg()),asyncio.create_task(self._input_handler()),asyncio.create_task(self._heartbeat()),]await asyncio.gather(*tasks)# 以下保持不变...
if __name__ == "__main__":controller = AsyncTTSController()try:asyncio.run(controller.run())except KeyboardInterrupt:asyncio.run(controller.stop())
"""
ffmpeg -y -i temp.wav -f s16le -acodec pcm_s16le -ar 24000 -ac 1 audio.raw
ffmpeg -ar 24000 -ac 1 -f s16le -i unix:/tmp/tts_audio.sock -f rtsp rtsp://localhost:8554/mystream
"""
- window10系统python10 可运行版本
主要让deepseek,执行了,socket 到 win32pipen的替换.因为本来就是换过去的.这一块的代码完全没有手工介入. 唯一改的是注释eng.endLoop(),并不用每次init() ,应改是pyttsx3的一个跨平台特性. ,异步的win32下支持稳定.
def _sync_tts(self, text, tmp_filename):eng = self.engine #pyttsx3.init()eng.save_to_file(text, 'temp3.wav')eng.runAndWait()# eng.endLoop()
main-win.py
import asyncio
import struct
import pyttsx3
import tempfile
import os
from aioconsole import ainput
from contextlib import suppress
from typing import Optional
import win32pipe
import win32file
import pywintypesclass AsyncTTSController:def __init__(self):# 使用Windows命名管道self.pipe_name = r'\\.\pipe\tts_audio_pipe'self.pipe_handle = None# 进程控制self.ffmpeg_process: Optional[asyncio.subprocess.Process] = Noneself.running = False# TTS引擎self.engine = pyttsx3.init()self.engine.setProperty('rate', 180)self.engine.setProperty('volume', 1.0)# 音频参数self.sample_rate = 24000self.channels = 1self.bits_per_sample = 16self.silence = self._generate_silence(0.2)self.wav_header = self._generate_wav_header()# 状态管理self.connection_active = Falseself.last_heartbeat = 0.0self.heartbeat_interval = 2.0self.sending_audio = 0def _generate_wav_header(self) -> bytes:"""生成WAV文件头"""byte_rate = self.sample_rate * self.channels * self.bits_per_sample // 8block_align = self.channels * self.bits_per_sample // 8return struct.pack('<4sI4s4sIHHIIHH4sI',b'RIFF', 36, b'WAVE', b'fmt ', 16, 1, self.channels,self.sample_rate, byte_rate, block_align, self.bits_per_sample,b'data', 0)def _generate_silence(self, duration: float) -> bytes:"""生成静音数据"""samples = int(self.sample_rate * duration)return bytes(samples * self.channels * (self.bits_per_sample // 8))async def _async_create_pipe(self) -> None:"""创建命名管道"""while self.running and not self.connection_active:try:# 创建命名管道self.pipe_handle = win32pipe.CreateNamedPipe(self.pipe_name,win32pipe.PIPE_ACCESS_DUPLEX,win32pipe.PIPE_TYPE_BYTE | win32pipe.PIPE_READMODE_BYTE | win32pipe.PIPE_WAIT,1, # 最大实例数65536, 65536, # 输入输出缓冲区大小0, # 默认超时None # 安全属性)# 异步等待连接loop = asyncio.get_running_loop()await loop.run_in_executor(None, win32pipe.ConnectNamedPipe, self.pipe_handle, None)self.connection_active = Trueprint("客户端已连接")await self._async_write_socket(self.wav_header)except pywintypes.error as e:if e.winerror == 536: # ERROR_PIPE_CONNECTEDself.connection_active = Trueprint("客户端已连接")elif e.winerror == 232: # 客户端断开print("客户端断开连接")self.connection_active = Falseif self.pipe_handle:win32file.CloseHandle(self.pipe_handle)self.pipe_handle = Noneawait asyncio.sleep(1)else:print(f"管道错误: {e}")await asyncio.sleep(1)except Exception as e:print(f"其他错误: {e}")await asyncio.sleep(1)async def _start_ffmpeg(self) -> None:"""启动FFmpeg进程"""with suppress(Exception):if self.ffmpeg_process:self.ffmpeg_process.terminate()await self.ffmpeg_process.wait()self.ffmpeg_process = await asyncio.create_subprocess_exec('ffmpeg','-f', 's16le','-ar', str(self.sample_rate),'-ac', str(self.channels),'-i', self.pipe_name,'-c:a', 'aac','-f', 'rtsp','-rtsp_transport', 'tcp','rtsp://localhost:8554/mystream',stdout=asyncio.subprocess.DEVNULL,stdin=asyncio.subprocess.DEVNULL,stderr=asyncio.subprocess.PIPE)asyncio.create_task(self._monitor_ffmpeg_errors())async def _monitor_ffmpeg_errors(self) -> None:"""监控FFmpeg错误输出"""while self.running and self.ffmpeg_process:line = await self.ffmpeg_process.stderr.readline()if not line:break# print(f"[FFmpeg Error] {line.decode().strip()}")async def _async_write_socket(self, data: bytes) -> None:"""安全写入管道"""try:if self.connection_active and self.pipe_handle:loop = asyncio.get_running_loop()await loop.run_in_executor(None, win32file.WriteFile, self.pipe_handle, data)except pywintypes.error as e:print(f"写入错误: {e}")self.connection_active = Falseawait self._reconnect_pipeline()except Exception as e:print(f"其他写入错误: {e}")self.connection_active = Falseasync def _reconnect_pipeline(self) -> None:"""完整重连流程"""print("启动重连流程...")self.connection_active = Falseif self.pipe_handle:win32file.CloseHandle(self.pipe_handle)self.pipe_handle = Noneawait asyncio.gather(self._async_create_pipe(),self._start_ffmpeg())async def _heartbeat(self) -> None:"""心跳维持机制"""while self.running:if self.connection_active:for i in range(10):if self.sending_audio < 0:await self._async_write_socket(self.silence)else:self.sending_audio -= 2await asyncio.sleep(0.2)else:await asyncio.sleep(0.5)def _sync_tts(self, text, tmp_filename):eng = pyttsx3.init()eng.save_to_file(text, 'temp3.wav')eng.runAndWait()# eng.endLoop()async def _tts_worker(self, text: str) -> None:"""异步TTS处理核心"""await asyncio.get_event_loop().run_in_executor(None, self._sync_tts, text, 'temp3.wav')try:proc = await asyncio.create_subprocess_exec('ffmpeg','-hide_banner','-loglevel', 'error','-y','-i', 'temp3.wav','-f', 's16le','-acodec', 'pcm_s16le','-ar', str(self.sample_rate),'-ac', str(self.channels),'-',stdout=asyncio.subprocess.PIPE)sum_bytes = 0while chunk := await proc.stdout.read(4096):sum_bytes += len(chunk)await self._async_write_socket(chunk)self.sending_audio = int(sum_bytes * 10 / 48000)print(f"写入数据 x0.1s: {self.sending_audio}")finally:if os.path.exists('temp3.wav'):os.remove('temp3.wav')async def _input_handler(self) -> None:"""异步输入处理"""while self.running:try:text = await ainput("请输入文本(输入q退出): ")if text.lower() == 'q':self.running = Falsebreakif text.strip():await self._tts_worker(text)except Exception as e:print(f"输入错误: {str(e)}")async def run(self) -> None:"""主运行循环"""self.running = Truetasks = [asyncio.create_task(self._async_create_pipe()),asyncio.create_task(self._start_ffmpeg()),asyncio.create_task(self._input_handler()),asyncio.create_task(self._heartbeat()),]await asyncio.gather(*tasks)async def stop(self) -> None:"""安全关闭"""self.running = Falsewith suppress(Exception):if self.ffmpeg_process:self.ffmpeg_process.terminate()await self.ffmpeg_process.wait()if self.pipe_handle:win32pipe.DisconnectNamedPipe(self.pipe_handle)win32file.CloseHandle(self.pipe_handle)print("所有资源已释放")if __name__ == "__main__":controller = AsyncTTSController()try:asyncio.run(controller.run())except KeyboardInterrupt:asyncio.run(controller.stop())
独立的ffmpeg启动和监控的独立代码
验证了一下rtsp断线重建连结,也验证了 上面 的main.py的socket server退出后,ffmpeg自动重启连接。 要使用这个更稳健球的程序,需要
注释main.py run中的asyncio.create_task( self._start_ffmpeg()),
代码不用修改,把管道名这个快, 彻底修改为,ffmpeg认识的window样式,就可运行.
r’\.\pipe\tts_audio_pipe’
ffmg,py
import asyncio
from contextlib import suppress
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')class FFmpegManager:def __init__(self):self.ffmpeg_process = Noneself._retry_count = 0self._max_retries = 5self._retry_lock = asyncio.Lock()self._is_running = Falseself.sample_rate=24000self.channels=1self.socket_path = "/tmp/tts_audio.sock"async def _start_ffmpeg(self) -> None:"""带自动重试的FFmpeg启动函数"""async with self._retry_lock:await self._safe_terminate()try:socketid = 'unix:' + self.socket_pathself.ffmpeg_process =await asyncio.create_subprocess_exec('ffmpeg','-f', 's16le','-ar', str(self.sample_rate),'-ac', str(self.channels),'-i', socketid, # 修改输入源为套接字路径'-c:a', 'aac','-f', 'rtsp','-rtsp_transport', 'tcp','rtsp://localhost:8554/mystream',stdout=asyncio.subprocess.DEVNULL,stdin=asyncio.subprocess.DEVNULL,stderr=asyncio.subprocess.PIPE)self._retry_count = 0 # 重置重试计数器asyncio.create_task(self._monitor_ffmpeg_errors())self._is_running = Trueexcept Exception as e:logging.error(f"FFmpeg启动失败: {str(e)}")await self._handle_retry()async def _monitor_ffmpeg_errors(self):"""增强型进程监控"""while self._is_running:logging.info("loop error cathch")stderr = await self.ffmpeg_process.stderr.readline()if stderr:logging.error(f"FFmpeg错误输出: {stderr.decode().strip()}")# 检测进程状态return_code = self.ffmpeg_process.returncodeif return_code is not None:logging.warning(f"FFmpeg异常退出,返回码: {return_code}")self._is_running = Falseawait self._handle_retry()breakasync def _handle_retry(self):"""智能重试策略"""if self._retry_count >= self._max_retries:logging.critical("达到最大重试次数,放弃重启")return# 指数退避算法delay = min(2 ** self._retry_count, 30) # 最大间隔30秒self._retry_count += 1logging.info(f"将在 {delay} 秒后尝试第 {self._retry_count} 次重启")await asyncio.sleep(delay)await self._start_ffmpeg()async def _safe_terminate(self):"""安全终止现有进程"""if self.ffmpeg_process:with suppress(Exception):self.ffmpeg_process.terminate()await self.ffmpeg_process.wait()self.ffmpeg_process = None
# 以下保持不变...
async def main():controller=FFmpegManager()try:await controller._start_ffmpeg()logging.info('rung')await asyncio.sleep(1160)except KeyboardInterrupt:logging.info(3)asyncio.run(controller._safe_terminate())
if __name__ == "__main__":asyncio.run(main())
相关文章:
文本转语音-音画适时推送rtsp并播放
文本语音 rtsp适时播放叫号系统的底层逻辑 发布Linux, unix socket 和window win32做为音频源的 python10下的(ffmpeg version 7.1) 可运行版本. 这两天在弄这个,前2篇是通过虚拟声卡,达到了最简单的一个逻辑,播放文本就从声卡发声࿰…...
clickhouse修改和删除数据
标题:ClickHouse中修改和删除数据的简易指南 在大数据时代,数据库技术的发展日新月异。作为一款专为实时分析设计的列式数据库管理系统,ClickHouse因其高效的查询性能而受到欢迎。照这么推测的话,对于那些习惯于传统SQL操作&…...
2025CSP-J 冲刺训练(1):二分
2025CSP-J 冲刺训练 1 一、二分查找函数1. 头文件2. 前提条件3. 功能函数3.1 lower_bound3.2 upper_bound 二、二分答案模板1. 前提条件2. 模板 三、典型例题1. 寻找固定的和1.1 审题1.2 分析1.3 参考答案 2. Snuke Festival2.1 审题2.2 分析2.3 参考答案 四、拓展例题1. 晒衣服…...
无公网IP也能远程控制Windows:Linux rdesktop内网穿透实战
文章目录 前言1. Windows 开启远程桌面2. Linux安装rdesktop工具3. Win安装Cpolar工具4. 配置远程桌面地址5. 远程桌面连接测试6. 设置固定远程地址7. 固定地址连接测试 前言 如今远程办公已经从一种选择变成了许多企业和个人的必修课,而如何在Linux系统上高效地访…...
Win10 访问 Ubuntu 18 硬盘
目录 方案一:使用Samba共享服务Ubuntu 18 端配置Windows 10 端访问 方案二:使用 SSHFS(需在 Windows 上安装 SSH 客户端)Ubuntu 18 端配置Windows 10 端配置 方案三:使用 FTP 服务Ubuntu 18 端配置Windows 10 端访问 方…...
算法.习题篇
算法 — 地大复试 模拟 while循环和MOD循环计数 1.约瑟夫问题 http://bailian.openjudge.cn/practice/3254 using namespace std;bool isNoPeople(vector<bool> c)//判断当前数组是否一个小孩都没有了 {bool nopeople true;for (bool ival : c){if ( ival true)nop…...
upload-labs文件上传
第一关 上传一个1.jpg的文件,在里面写好一句webshell 保留一个数据包,将其中截获的1.jpg改为1.php后重新发送 可以看到,已经成功上传 第二关 写一个webshell如图,为2.php 第二关在过滤tpye的属性,在上传2.php后使用b…...
一二三应用开发平台——能力扩展:多数据源支持
背景 随着项目规模的扩大,单一数据源已无法满足复杂业务需求,多数据源应运而生。 技术选型 MyBatis-Plus 的官网提供了两种多数据源扩展插件:开源生态的 <font style"color:rgb(53, 56, 65);">dynamic-datasource</fon…...
【Python】整数除法不正确,少1的问题,以及有关浮点数转换的精度问题
1. 问题 今天在做leetcode 不同路径 的时候发现了个问题 对于m53 n4class Solution:def uniquePaths(self, m: int, n: int) -> int:rlt 1for i in range(0, m-1):rlt * (m n - 2 - i)for i in range(0, m-1):rlt / (i 1)return int(rlt)为什么这个结果是 26234class S…...
【贪心算法】简介
1.贪心算法 贪心策略:解决问题的策略,局部最优----》全局最优 (1)把解决问题的过程分成若干步 (2)解决每一步的时候,都选择当前看起来的“最优”的算法 (3)“希望”得…...
狮子座大数据分析(python爬虫版)
十二星座爱情性格 - 星座屋 首先找到一个星座网站,作为基础内容,来获取信息 网页爬取与信息提取 我们首先利用爬虫技术(如 Python 中的 requests 与 BeautifulSoup 库)获取页面内容。该页面(xzw.com/astro/leo/&…...
【商城实战(20)】商品管理功能深化实战
【商城实战】专栏重磅来袭!这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建,运用 uniapp、Element Plus、SpringBoot 搭建商城框架,到用户、商品、订单等核心模块开发,再到性能优化、安全加固、多端适配…...
YC 孵化项目 Pinch:实时语音翻译视频会议平台;Mistral OCR:能处理多语言多模态复杂文档丨日报
开发者朋友们大家好: 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。 我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 技术 」、「有亮点的 产品 」、「有思考的 文章 」、「有态度的 …...
数据库原理6
1.数据是信息的载体 2.数据库应用程序人员的主要职责:编写应用系统的程序模块 3.关系规范化理论主要属于数据库理论的研究范畴 4.数据库主要有检索和修改(包括插入,删除,更新)两大操作 5.概念模型又称为语义模型。…...
深度学习与大模型基础-向量
大家好!今天我们来聊聊向量(Vector)。别被这个词吓到,其实向量在我们的生活中无处不在,只是我们没注意罢了。 1. 向量是什么? 简单来说,向量就是有大小和方向的量。比如你从家走到学校&#x…...
OpenManus:3小时复刻 Manus(OpenManus安装指南)
项目地址:GitHub - mannaandpoem/OpenManus: No fortress, purely open ground. OpenManus is Coming. 安装指南 我们提供两种安装方式。推荐使用方式二(uv),因为它能提供更快的安装速度和更好的依赖管理。 方式一:使…...
2025年渗透测试面试题总结-快某手-安全实习生(一面、二面)(题目+回答)
网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 快某手-安全实习生 一面 一、Linux操作:查看进程PID的5种方法 二、Elasticsearch&#x…...
【微信小程序】uniapp开发微信小程序
uniapp开发微信小程序 1、上拉加载 下拉刷新 import { onReachBottom, onPullDownRefresh } from dcloudio/uni-app;配置允许下拉刷新: {"path" : "pages/pet/pet","style" : {"navigationBarTitleText" : ""…...
动态规划_最大子数组和
53. 最大子数组和 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组是数组中的一个连续部分。 示例 1:输入:nums [-2,1,-3,4,-1,2,1,-5,4] …...
从零开始的python学习(五)P71+P72+P73+P74
本文章记录观看B站python教程学习笔记和实践感悟,视频链接:【花了2万多买的Python教程全套,现在分享给大家,入门到精通(Python全栈开发教程)】 https://www.bilibili.com/video/BV1wD4y1o7AS/?p6&share_sourcecopy_web&v…...
Vue3实战学习(Element-Plus常用组件的使用(输入框、下拉框、单选框多选框、el-image图片))(上)(5)
目录 一、Vue3工程环境配置、项目基础脚手架搭建、Vue3基础语法、Vue3集成Element-Plus的详细教程。(博客链接如下) 二、Element-Plus常用组件使用。 (1)el-input。(input输入框) <1>正常状态的el-input。 <2>el-input的disable状态。 <3…...
HarmonyOS学习第18天:多媒体功能全解析
一、开篇引入 在当今数字化时代,多媒体已经深度融入我们的日常生活。无论是在工作中通过视频会议进行沟通协作,还是在学习时借助在线课程的音频讲解加深理解,亦或是在休闲时光用手机播放音乐放松身心、观看视频打发时间,多媒体功…...
多模态融合的分类、跨模态对齐的方法
两者的主要区别 维度扩模态对齐扩模态融合目标对齐模态间的表示,使其语义一致融合模态间的信息,生成联合表示关注点模态间的相似性和语义一致性模态间的互补性和信息整合空间映射到共享的公共语义空间生成新的联合特征空间方法对比学习、共享空间、注意…...
软件高级架构师 - 软件工程
补充中 测试 测试类型 静态测试 动态测试 测试阶段 单元测试中,包含性能测试,如下: 集成测试中,包含以下: 维护 遗留系统处置 高水平低价值:采取集成 对于这类系统,采取 集成 的方式&…...
Uniapp项目运行到微信小程序、H5、APP等多个平台教程
摘要:Uniapp作为一款基于Vue.js的跨平台开发框架,支持“一次开发,多端部署”。本文将手把手教你如何将Uniapp项目运行到微信小程序、H5、APP等多个平台,并解析常见问题。 一、环境准备 在开始前,请确保已安装以下工具…...
【JavaWeb12】数据交换与异步请求:JSON与Ajax的绝妙搭配是否塑造了Web的交互革命?
文章目录 🌍一. 数据交换--JSON❄️1. JSON介绍❄️2. JSON 快速入门❄️3. JSON 对象和字符串对象转换❄️4. JSON 在 java 中使用❄️5. 代码演示 🌍二. 异步请求--Ajax❄️1. 基本介绍❄️2. JavaScript 原生 Ajax 请求❄️3. JQuery 的 Ajax 请求 &a…...
2025-03-10 吴恩达机器学习1——机器学习概述
文章目录 1 监督学习1.1 回归1.2 分类 2 无监督学习2.1 聚类2.2 异常检测2.3 降维 3 使用 Jupyter Notebook 1959 年,Arthur Samuel 将机器学习定义如下: Field of study that gives computers the ability to learn without being explicitly pro…...
Spring Boot整合WebSocket
目录 ?引言 1.WebSocket 基础知识 ?1.1 什么是 WebSocket? ?1.2 WebSocket 的应用场景 ?2.Spring Boot WebSocket 整合步骤 2.1 创建 Spring Boot 项目 2.2 添加 Maven 依赖 2.3 配置 WebSocket 2.4 创建 WebSocket 控制器 2.5 创建前端页面 引言 在…...
PostgreSQL - Windows PostgreSQL 下载与安装
Windows PostgreSQL 下载与安装 1、PostgreSQL 下载 下载地址:https://www.enterprisedb.com/downloads/postgres-postgresql-downloads 2、PostgreSQL 安装 启动安装程序 -> 点击 【Next】 指定安装路径 -> 点击 【Next】 默认勾选 -> 点击 【Next】 指…...
【Java面试题汇总】Java面试100道最新合集!
1.说说你对面向对象的理解 得分点 封装,继承,多态、概念、实现方式和优缺点 面向对象的三大基本特征是:封装、继承、多态。 封装:将对象的状态和行为包装在一个类中并对外界隐藏实现的细节,可以通过访问修饰符控制成员的访问权限,…...
【LLM】kimi 1.5模型架构和训练流程
note 推出两个多模态模型,深度思考模型 long-CoT 对标 o1,通用模型 short-CoT 模型对标 gpt-4o。 文章目录 note一、kimi 1.5模型训练流程预训练SFT训练long-CoT SFTRL训练long2short 小结Reference 一、kimi 1.5模型训练流程 推出两个多模态模型&…...
Android Studio 配置国内镜像源
Android Studio版本号:2022.1.1 Patch 2 1、配置gradle国内镜像,用腾讯云 镜像源地址:https\://mirrors.cloud.tencent.com/gradle 2、配置Android SDK国内镜像 地址:Index of /AndroidSDK/...
永洪科技深度分析实战,零售企业的销量预测
随着人工智能技术的不断发展,智能预测已经成为各个领域的重要应用之一。现在,智能预测技术已经广泛应用于金融、零售、医疗、能源等领域,为企业和个人提供决策支持。 智能预测技术通过分析大量的数据,利用机器学习和深度学习算法…...
Pytorch实现之利用CGAN鉴别真假图像
简介 简介:利用生成对抗网络来鉴别是真图像还是假图像。 论文题目:Detection and Identification of Fake Images Using Conditional Generative Adversarial Networks (CGANs) (基于条件生成对抗网络(CGAN)的假图像检测与识别) 会议:16th IEEE International Confer…...
开源模型时代的 AI 开发革命:Dify 技术深度解析
开源模型时代的AI开发革命:Dify技术深度解析 引言:AI开发的开源新纪元 在生成式AI技术突飞猛进的2025年,开源模型正成为推动行业创新的核心力量。据统计,全球超过80%的AI开发者正在使用开源模型构建应用,这一趋势不仅…...
网络DNS怎么更改?
访问速度慢或某些网站无法打开?改变网络DNS设置可能会帮助解决这些问题。本文将详细介绍如何更改网络DNS,包括更改的原因、具体步骤。 一、为什么要更改DNS? 更改DNS的原因有很多,以下是一些主要的考虑因素:某些公共DNS服务器的响应速度比…...
计算机网络篇:基础知识总结与基于长期主义的内容更新
基础知识总结 和 MySQL 类似,我同样花了一周左右的时间根据 csview 对计算机网络部分的八股文进行了整理,主要的内容包括:概述、TCP 与 UDP、IP、HTTP,其中我个人认为最重要的是 TCP 这部分的内容。 在此做一篇目录索引…...
使用miniforge安装python并用pycharm打开使用
1.安装miniforge 参考文章:https://blog.csdn.net/loujiand/article/details/119976302 https://blog.csdn.net/qq_41946216/article/details/129481760 下载地址: 先从github下载miniforge:https://github.com/conda-forge/miniforge 2.使用conda命令…...
如何实现wordpress搜索自字义字段内容
有些网站需要根据自定义段字的内容来做为搜索项,比如,房产中介公司wordpress网站,需要搜索同一区域内容的楼盘,然后展示出内容。 不废话了,在function.php直接加上代码 add_action(posts_search, function($search, …...
【华为OD机考真题】- 星际篮球争霸赛(Java)
1. 题目描述 具体题目描述如下: 在星球争霸篮球赛对抗赛中,最大的宇宙战队希望每个人都能拿到 MVP,MVP 的条件是单场最高分得分获得者。 可以并列,所以宇宙战队决定在比赛中,尽可能让更多队员上场,并且让所有得分的选手…...
LeetCode 376. 摆动序列 java题解
https://leetcode.cn/problems/wiggle-subsequence/description/ 只要不满足摆动条件,就不更新count和prediff 当 prevDiff 取等号时,比如 prevDiff 0,在这种情况下,如果 currDiff > 0,说明从持平状态转变为上升…...
PyCharm 接入 DeepSeek、OpenAI、Gemini、Mistral等大模型完整版教程(通用)!
PyCharm 接入 DeepSeek、OpenAI、Gemini、Mistral等大模型完整版教程(通用)! 当我们成功接入大模型时,可以选中任意代码区域进行解答,共分为三个区域,分别是选中区域、提问区域以及回答区域,我…...
使用RabbitMQ实现流量削峰填谷
原理 流量削峰填谷是指在面对突发的高流量时,通过消息队列将瞬时大量请求暂时存储起来,并逐步处理这些请求,从而避免系统过载。RabbitMQ 作为消息中间件可以很好地支持这一需求,特别是结合其延时消息插件(rabbitmq_de…...
Apache Commons Lang3 和 Commons Net 详解
目录 1. Apache Commons Lang3 1.1 什么是 Apache Commons Lang3? 1.2 主要功能 1.3 示例代码 2. Commons Net 2.1 什么是 Commons Net? 2.2 主要功能 2.3 示例代码 3. 总结 3.1 Apache Commons Lang3 3.2 Commons Net 3.3 使用建议 4. 参考…...
ACE学习2——write transaction
用于处理缓存行的数据更新到主内存(main memory)的操作。 以下是用于更新主内存的几种事务类型: WriteBack: WriteBack事务用于将cache中的dirty态的cacheline写回主存,以释放cache中的cacheline,用于存…...
mac本地安装运行Redis-单机
记录一下我以前用的连接服务器的跨平台SSH客户端。 因为还要准备毕设...... 服务器又过期了,只能把redis安装下载到本地了。 目录 1.github下载Redis 2.安装homebrew 3.更新GCC 4.自行安装Redis 5.通过 Homebrew 安装 Redis 安装地址:https://git…...
sparkTTS window 安装
SparkTTS 的简介 Spark-TTS是一种基于SpardAudio团队提出的 BiCodec 构建的新系统,BiCodec 是一种单流语音编解码器,可将语音策略性地分解为两种互补的标记类型:用于语言内容的低比特率语义标记和用于说话者特定属性的固定长度全局标记。这种…...
颠覆语言认知的革命!神经概率语言模型如何突破人类思维边界?
颠覆语言认知的革命!神经概率语言模型如何突破人类思维边界? 一、传统模型的世纪困境:当n-gram遇上"月光族难题" 令人震惊的案例:2012年Google语音识别系统将 用户说:“我要还信用卡” 系统识别ÿ…...
大语言模型从理论到实践(第二版)-学习笔记(绪论)
大语言模型的基本概念 1.理解语言是人工智能算法获取知识的前提 2.语言模型的目标就是对自然语言的概率分布建模 3.词汇表 V 上的语言模型,由函数 P(w1w2 wm) 表示,可以形式化地构建为词序列 w1w2 wm 的概率分布,表示词序列 w1w2 wm…...
2.1 Vite + Vue 3 + TS 项目脚手架深度配置
文章目录 **一、环境准备与技术选型****二、项目初始化与基础架构****三、工程化配置深度优化****四、代码规范与质量保障****五、Vue 3 深度集成****六、TypeScript 高级配置****七、第三方库集成****八、构建优化策略****九、企业级最佳实践****十、扩展配置参考****本章核心…...