阿里云ECS挂载OSS教程
1.下载依赖环境
yum install automake gcc-c++ git libcurl-devel libxml2-devel fuse-devel make openssl-devel -y
2.下载ossfs
(1)git下载ossfs代码(阿里云放在了github上,自己的服务器又访问不了,所以三叔做了镜像)
git clone https://gitee.com/bejson/ossfs.git
(2)编译安装
cd ossfs
./autogen.sh
./configure
make && make install #默认应该是安装在/usr/local/bin/
3. 安装fuse
sudo wget https://gosspublic.alicdn.com/ossfs/ossfs_1.80.7_centos7.0_x86_64.rpm
sudo yum install ossfs_1.80.7_centos7.0_x86_64.rpm
4. 配置阿里云OSS秘钥
例如:
echo my-bucket:my-access-key-id:my-access-key-secret > /etc/passwd-ossfs
chmod 640 /etc/passwd-ossfs
5. 在ECS实例上创建一个本地目录,用于挂载OSS Bucket。可以通过以下命令创建:
sudo mkdir /mnt/oss
6. 使用OSSFS挂载Bucket。可以通过以下命令挂载:
sudo ossfs <BucketName> /mnt/oss -ourl=<Endpoint> -o nonempty -o allow_other -o use_cache=/tmp
#比如:sudo ossfs 5xxx your_dir -ourl=http://oss-cn-beijing-internal.aliyuncs.com -ouid=your_uid -ogid=your_gid
ps:
如果上传本地文件
cp /mnt/oss/<ObjectName> <LocalFile>
其中,<LocalFile>
是本地文件的路径,<ObjectName>
是在OSS Bucket中的对象名称。
下载OSS Bucket中的数据到本地,可以通过以下命令下载:
cp /mnt/oss/<ObjectName> <LocalFile>
其中,<LocalFile>
是下载到本地的文件路径,<ObjectName>
是在OSS Bucket
中的对象名称。
PHP实现微信小程序多语音效果技巧
随着移动互联网的发展,微信小程序已经成为了许多企业和开发者的首选开发平台。而在小程序开发过程中,语音效果是非常重要的一个环节。本文将介绍PHP实现微信小程序多语音效果的技巧。
一、微信小程序语音效果的基本介绍
在微信小程序中,语音效果的实现主要通过微信小程序的API接口来实现。需要注意的是,微信小程序的语音效果主要分为两种:语音合成和语音识别。
1.语音合成
所谓语音合成,就是将文字转换为语音进行播放。在微信小程序中,我们可以通过调用微信小程序的语音API接口,将需要转换成语音的文字发送到微信服务器,并获取到返回的语音文件地址,将其播放即可。
2.语音识别
语音识别就是将语音转换为文字,常用于语音输入、语音搜索等场景。在微信小程序中,我们同样可以调用微信小程序的语音API接口,将需要识别的语音文件发送到微信服务器,并获取到返回的文字结果,然后进行后续数据处理。
二、PHP实现微信小程序语音效果的方式
上文提到了微信小程序语音效果的两种实现方式,那么在PHP中,我们又该如何调用微信小程序提供的语音API接口来实现语音效果呢?具体步骤如下:
1.获取access_token
在向微信服务器发送API请求时,我们需要先获取一个access_token,以获取API调用的权限。获取access_token的方式有多种,本文将介绍一种常用的方式:
$appid = "你的小程序appid";
$secret = "你的小程序secret";
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$secret";
$res = file_get_contents($url);
$res = json_decode($res, true);
$access_token = $res['access_token'];
2.调用语音合成API
在获取了access_token之后,我们就可以调用微信小程序提供的语音合成API了。具体步骤如下:
$url = "https://api.weixin.qq.com/cgi-bin/media/voice/addvoicetorecofortext?access_token=$access_token";
$data = array(
'voice_text' => '需要合成语音的文字',
'format' => 'mp3'
);
$data = json_encode($data);
$options = array(
'http' => array(
'method' => 'POST',
'header' => "Content-type:application/json",
'content' => $data,
'timeout' => 60
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$result = json_decode($result, true);
$voice_url = $result['voice_url'];
在上述代码中,我们将需要合成语音的文字传递给语音合成API,并指定合成的格式为mp3。在获取到返回的voice_url之后,我们就可以拿到语音文件的地址,将其播放即可。
3.调用语音识别API
除了语音合成之外,我们还可以通过调用微信小程序提供的语音识别API,将语音文件转换为文字。具体步骤如下:
$url = "https://api.weixin.qq.com/cgi-bin/media/voice/queryrecoresultfortext?access_token=$access_token";
$data = array(
'voice_url' => '需要识别的语音文件地址'
);
$data = json_encode($data);
$options = array(
'http' => array(
'method' => 'POST',
'header' => "Content-type:application/json",
'content' => $data,
'timeout' => 60
)
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$result = json_decode($result, true);
$voice_text = $result['voice_text'];
在上述代码中,我们将需要识别的语音文件地址传递给语音识别API,并获取到返回的voice_text结果,进行后续数据处理即可。
三、总结
通过上述的介绍,相信读者们已经了解了使用PHP实现微信小程序语音效果的方法。需要注意的是,在实际开发过程中,我们需要根据具体的场景和业务需求,进行相应的API调用和数据处理。希望本文能够对大家有所帮助,为微信小程序的开发和应用带来更多的可能性。
以上就是PHP实现微信小程序多语音效果技巧的详细内容,更多请关注php中文网其它相关文章!
收起阅读 »目前市面上AI模型价格对比
openai接口
模型名称 | 资费(输入) | 资费(输出) | 字数上限 (含上下文) |
gpt-3.5-turbo | $0.001 / K | $0.002 / k | 4K |
gpt-3.5-turbo-0613 | $0.001 / K | $0.002 / k | 4K |
gpt-3.5-turbo-1106 | $0.001 / K | $0.002 / k | 输入16K,输出4K |
gpt-3.5-turbo-16k | $0.002 / k | $0.004 / k | 16K |
gpt-3.5-turbo-16k-0613 | $0.002 / k | $0.004 / k | 16k |
gpt-4 | $0.03 / k | $0.06 / k | 8K |
gpt-4-0613 | $0.01 / k | $0.03 / k | 8K |
gpt-4-1106-preview | $0.01 / K | $0.03 / k | 输入128k,输出4K |
gpt-4-vision-preview | $0.01 / K | $0.03 / k | 输入128k,输出4K |
gpt-4-32k | $0.01 / K | $0.12 / k | 32K |
gpt-4-32k-0613 | $0.01 / K | $0.12 / k | 32K |
百度文心一言
注:1token 约等于 1个汉字 或者 1.3 个单词
模型名称 | 资费 |
ERNIE-Bot | 0.012元/千tokens |
ERNIE-Bot-turbo | 0.008元/千tokens |
Llama-2-13B-Chat | 0.006元/千tokens |
Llama-2-70B-Chat | 0.035元/千tokens |
ChatGLM2-6B-32K | 0.004元/千tokens |
ERNIE-Bot-4 | 0.12元/千tokens |
讯飞星火
1tokens 约等于1.5个中文汉字 或者 0.8个英文单词
服务引擎 | 单价 |
讯飞星火认知大模型V1.5 | 0.018元/千tokens |
讯飞星火认知大模型V2.0 | 0.036元/千tokens |
讯飞星火认知大模型V3.0 | 0.036元/千tokens |
通义千问
1token约等于1个中文汉字 或者 3至4个英文字母
模型名称 | 单价 |
qwen-turbo | 0.008元/千tokens |
qwen-plus | 0.02元/千tokens |
腾讯混元
1token 约等于1.8个中文汉字或3个英文字母
模型名称 | 单价 |
腾讯混元大模型标准版 | 0.01元 / 千tokens |
腾讯混元大模型高级版 | 0.1元 / 千tokens |
腾讯混元-Embedding | 0.0007元 / 千tokens |
通义千问
1token 约等于1.8个中文汉字或3个英文字母
模型名称 | 单价 |
qwen-turbo | 0.008元 / 千tokens |
qwen-plus | 0.02元 / 千tokens |
qwen-max | 限时免费 |
qwen-max-1201 | |
qwen-max-longcontext |
智谱AI
1token 约等于1.8个中文汉字
模型 | 说明 | 上下文长度 | 单价 |
GLM-4 | 提供了更强大的问答和文本生成能力。适合于复杂的对话交互和深度内容创作设计的场景。 | 128K | 0.1元 / 千tokens |
GLM-3-Turbo | 适用于对知识量、推理能力、创造力要求较高的场景,比如广告文案、小说写作、知识类写作、代码生成等。 | 128K | 0.005元 / 千tokens |
MINIMAX
1000个token约对应750个字符文本(包括标点等字符)
模型名称 | 单价 |
abab6 | 0.2元/千tokens |
abab5.5 | 0.015元/千tokens |
abab5.5s | 0.005元/千tokens |
Claude2
模型名称 | 单价(输入) | 单价(输出) |
claude-1 | $0.008/千tokens | $0.024/千tokens |
claude-2 | $0.008/千tokens | $0.024/千tokens |
Gemini
模型名称 | 价格 |
gemini-pro | 免费中 |
许可证 cc0-1.0 和 MIT 区别
CC0 1.0 和 MIT 许可证都是非常宽松的许可证,它们允许人们广泛地使用、修改和重新分发软件,但它们在某些关键方面有所不同:
目的和范围:
CC0 1.0: 由创意共享(Creative Commons)发布,旨在放弃版权和相关权利,使作品尽可能接近公有领域。CC0 可以用于软件,但更常用于其他类型的创作,如艺术作品、教育材料和科学数据。
MIT 许可证: 是一个专门为软件和源代码设计的许可证,提供了明确的允许、复制、修改和分发软件的条款。
版权和放弃声明:
CC0 1.0: 该许可证旨在放弃所有版权和相关权利。虽然在版权法律强制执行的地区(如美国)可能无法完全放弃版权,但 CC0 尽可能接近于这个目标。
MIT 许可证: 保留版权声明,但允许在几乎没有限制的情况下使用软件。版权持有者保留版权,但用户几乎可以无限制地使用软件。
责任限制:
CC0 1.0: 不提供任何形式的保证。它尝试放弃所有责任。
MIT 许可证: 明确声明软件是“按原样”提供,不附带任何形式的保证,将风险转移到使用者身上。
常见用途:
CC0 1.0: 通常用于那些创作者希望将其作品贡献给公共领域的情况。
MIT 许可证: 主要用于软件和源代码,是开源社区中最受欢迎的许可证之一。
总之,虽然两者都提供了很大的自由度,但 CC0 1.0 更接近于版权放弃,而 MIT 许可证则保留了版权但几乎不限制软件的使用。在选择适合你项目的许可证时,考虑这些差异非常重要。
收起阅读 »CSharp下载ffpmeg
先定义这个方法:
private async Task CheckFfmpegAsync()
{
string ffmpegPath = Path.Combine(_workingDirectory, "ffmpeg");
if (!Directory.Exists(ffmpegPath))
{
Directory.CreateDirectory(ffmpegPath);
}
FFmpeg.SetExecutablesPath(ffmpegPath);
_logger.Information("Checking FFmpeg...");
if (Directory.GetFiles(ffmpegPath).Length == 0)
{
_logger.Information("FFmpeg not found - downloading...");
await FFmpegDownloader.GetLatestVersion(FFmpegVersion.Official, FFmpeg.ExecutablesPath, new FFMpegDownloadingProgress(Log.Logger));
_logger.Information("FFmpeg downloaded");
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
Exec("chmod +x " + Path.Combine(ffmpegPath, "ffmpeg"));
Exec("chmod +x " + Path.Combine(ffmpegPath, "ffprobe"));
}
}
}
然后在代码里使用
private async Task CheckFfmpegAsync()
{
string ffmpegPath = Path.Combine(_workingDirectory, "ffmpeg");
if (!Directory.Exists(ffmpegPath))
{
Directory.CreateDirectory(ffmpegPath);
}
FFmpeg.SetExecutablesPath(ffmpegPath);
_logger.Information("Checking FFmpeg...");
if (Directory.GetFiles(ffmpegPath).Length == 0)
{
_logger.Information("FFmpeg not found - downloading...");
await FFmpegDownloader.GetLatestVersion(FFmpegVersion.Official, FFmpeg.ExecutablesPath, new FFMpegDownloadingProgress(Log.Logger));
_logger.Information("FFmpeg downloaded");
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
Exec("chmod +x " + Path.Combine(ffmpegPath, "ffmpeg"));
Exec("chmod +x " + Path.Combine(ffmpegPath, "ffprobe"));
}
}
}
这样的话就会判断有没有下载ffmpeg没有就会下载:
然后就可以使用CMD执行了。
private void Exec(string cmd)
{
var escapedArgs = cmd.Replace("\"", "\\\"");
using var process = new Process
{
StartInfo = new ProcessStartInfo
{
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "/bin/bash",
Arguments = $"-c \"{escapedArgs}\""
}
};
try
{
process.Start();
process.WaitForExit();
}
catch (Exception ex)
{
_logger.Error(ex, "Error occurred while executing command: {cmd}", cmd);
}
}
指定代码:
await FFmpegDownloader.GetLatestVersion(FFmpegVersion.Official, FFmpeg.ExecutablesPath, new FFMpegDownloadingProgress(Log.Logger));
_logger.Information("FFmpeg downloaded");
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
Exec("chmod +x " + Path.Combine(ffmpegPath, "ffmpeg"));
Exec("chmod +x " + Path.Combine(ffmpegPath, "ffprobe"));
}
SpringBoot里有多少种 ContextHolder 有分别有啥用
在Spring Boot以及Spring框架中,有几个常见的ContextHolder
类,它们在应用程序中扮演着重要的角色。主要有以下几种:
SecurityContextHolder
:用途:这是Spring Security中的一个核心组件,用于存储当前执行线程的安全上下文(
SecurityContext
),其中通常包含当前用户的详细信息。这对于实现基于Spring Security的认证和授权非常关键。功能:它提供了一个线程局部存储(ThreadLocal),用于存储认证对象(如用户的认证信息)。
RequestContextHolder
:用途:这是Spring Web中的一个组件,用于存储与当前HTTP请求相关的数据。
功能:它可以让你在没有直接访问到
HttpServletRequest
和HttpServletResponse
对象的情况下,仍能获取这些对象。这在非请求处理流程中特别有用,比如在服务层或组件中访问请求或会话作用域的数据。LocaleContextHolder
:用途:这是Spring的一个组件,用于处理国际化和本地化。
功能:它提供了一个线程局部存储,用于存储
Locale
和TimeZone
信息,使得在整个请求处理流程中可以方便地访问这些信息。ApplicationContextHolder
(如果你是指ApplicationContextAware
接口):用途:这是Spring框架的一个部分,用于访问Spring的应用上下文(
ApplicationContext
)。功能:通过实现
ApplicationContextAware
接口,你的组件可以获得对ApplicationContext
的引用,从而能够访问Spring容器中的各种资源和服务。
每个ContextHolder
都是为了解决特定的问题而设计的。SecurityContextHolder
用于安全相关的操作,RequestContextHolder
用于处理请求作用域的数据,LocaleContextHolder
用于国际化和本地化支持,而ApplicationContextHolder
(或类似的机制)用于访问Spring的应用上下文。这些类都是Spring框架内部协同工作的一部分,使得开发者可以更方便地构建企业级应用程序。
JSON Web Token(JWT)的详细介绍
JSON Web Token(JWT)是一种开放的标准,用于在网络应用程序和服务之间安全地传递信息。它是一个紧凑的、自包含的数据结构,通常用于身份验证和授权领域,特别是在分布式系统中。
JWT由三个部分组成,这三个部分之间使用句点.分隔开来:
头部(Header): JWT的头部通常包含两个部分,指定了JWT的元信息和加密算法。头部是一个JSON对象,通常包含以下两个属性:
一个示例头部可以如下所示:
jsonCopy code{
"alg": "HS256",
"typ": "JWT"}"alg":表示用于签名JWT的加密算法,例如"HMAC SHA256"或"RSA"。
"typ":通常设置为"JWT",表示这是一个JWT令牌。
载荷(Payload): 载荷是JWT的第二部分,它包含了一些声明(claims),这些声明是关于实体(通常是用户)和其他数据的JSON对象。JWT有三种类型的声明:
一个示例载荷可以如下所示:
jsonCopy code{
"sub": "1234567890",
"name": "John Doe",
"exp": 1619016159}"iss"(签发者):表示生成JWT的实体。
"sub"(主题):表示JWT所描述的实体,通常是用户的唯一标识。
"aud"(受众):表示JWT的预期接收者。
"exp"(过期时间):表示JWT的过期时间,以Unix时间戳形式表示。
"nbf"(生效时间):表示JWT的生效时间,以Unix时间戳形式表示。
"iat"(签发时间):表示JWT的签发时间,以Unix时间戳形式表示。
"jti"(JWT ID):表示JWT的唯一标识符。
注册声明(Registered Claims):这些是一些预定义的声明,包括:
私有声明(Private Claims):这些是自定义的声明,用于传递应用程序特定的信息。
公共声明(Public Claims):这些是被定义为可用于共享信息的声明。
签名(Signature): 为了确保JWT的完整性和真实性,签名是JWT的第三部分。签名是由头部和载荷组成的数据经过指定的加密算法和密钥计算得出的。接收方可以使用相同的密钥和算法来验证签名,从而确保JWT在传输过程中没有被篡改。
整个JWT令牌的结构如下所示:
cssCopy code[头部].[载荷].[签名]
JWT的主要优点包括:
自包含性:JWT包含所有必要的信息,无需服务器存储会话状态。
安全性:通过签名来验证JWT的完整性,防止篡改。
可扩展性:可以自定义声明以满足应用程序的需求。
跨域通信:JWT可用于跨域通信,因为它可以在各种环境中传递,如浏览器和服务器之间的通信。
JWT通常在身份验证过程中生成并在客户端和服务器之间传递,以证明用户的身份并获得访问授权。服务器可以验证JWT的签名并提取其中的信息以进行相应的操作。由于其灵活性和安全性,JWT在现代应用程序中广泛使用。
jwt解码校验签名工具上线
可以对jwt生成的token进行解码。
https://www.devtools.cn/enc/jwtdecode/
可以进行jwt的token解码以及签名验证。
不过签名验证需要输入当时加密时候的密钥。
springboot 使用websocket 怎么写代码 需要什么依赖
要使用WebSocket,您需要在Spring Boot项目中添加以下依赖项:
1. Maven依赖项:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2. Gradle依赖项:
implementation 'org.springframework.boot:spring-boot-starter-websocket'
接下来,您需要编写WebSocket处理程序和配置类。
1. 创建一个WebSocket处理程序:
import org.springframework.stereotype.Component;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
@Component
public class MyWebSocketHandler extends AbstractWebSocketHandler {
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// 处理收到的文本消息
String payload = message.getPayload();
// ...
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// 当WebSocket连接建立时执行的操作
// ...
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
// 当WebSocket连接关闭时执行的操作
// ...
}
}
2. 创建一个WebSocket配置类:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
private final MyWebSocketHandler webSocketHandler;
public WebSocketConfig(MyWebSocketHandler webSocketHandler) {
this.webSocketHandler = webSocketHandler;
}
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(webSocketHandler, "/websocket").setAllowedOrigins("*");
}
}
在这个配置类中,我们将WebSocket处理程序注册为"/websocket"路径的处理程序,并允许所有来源的连接。
这样,您就可以使用WebSocket了。您可以在控制器中注入`MyWebSocketHandler`并使用它来处理WebSocket连接。