作者: ethan

  • python文字转语音(mac)

    随着自媒体的兴起,文字转语音服务的需求越来越大,下面介绍下如何自己用python脚本实现文字语音

    第一步: 注册百度开发者账号

    https://ai.baidu.com/tech/speech

    第二步:安装相关扩展

    pip3 install baidu-aip
    pip3 install playsound
    pip3 install pyobjc

    第三步:代码

    from aip import AipSpeech
    from playsound import playsound
    
    APP_ID = 'xxxx'
    API_KEY = 'xxxx'
    SECRET_KEY = 'xxxx'
    client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
    
    # text 合成的文本,使用UTF-8编码。小于2048个中文字或者英文数字。
    text = '春种一粒粟,秋收万颗子。四海无闲田,农夫犹饿死。'
    
    # spd 语速,取值0-15,默认为5中语速
    spd = 5
    # pit 音调,取值0-15,默认为5中语调
    pit = 5
    # vol 音量,取值0-15,默认为5中音量
    vol = 5
    # per per(基础音库) 度小宇=1,度小美=0,度逍遥=3,度丫丫=4;(精品音库)度博文=106,度小童=110,度小萌=111,度米朵=103,度小娇=5
    per = 0
    # aue 3为mp3格式(默认); 4为pcm-16k;5为pcm-8k;6为wav(内容同pcm-16k); 注意aue=4或者6是语音识别要求的格式,但是音频内容不是语音识别要求的自然人发音,所以识别效果会受影响。
    aue = 3
    
    result = client.synthesis(text, 'zh', 1, {
        'spd': spd,
        'pit': pit,
        'vol': vol,
        'per': per,
        'aue': aue
    })
    
    audio_file = 'auido.mp3'
    
    # 生成音频文件
    if not isinstance(result, dict):
        with open(audio_file, 'wb') as f:
            f.write(result)
    
    # mac播放音频文件
    playsound(audio_file)
  • redis限制请求频率

    通过redis限制请求的频率

    场景1: 限制用户每分钟获取验证码频率,如一分钟不能超过3次

    <?php
    /**
     * 场景4:限速
     *
     * @package    scene04.php
     * @author     ethan<toethanxu@outlook.com>
     * @version    2020/6/14
     */
    
    require_once '../../CacheRedis.php';
    
    $server = '127.0.0.1:6379';
    $redis = CacheRedis::getInstance($server);
    
    // 限速
    
    $keyPrefix = 'phone:limit:';
    $phone = 15111111111;
    $key = $keyPrefix . $phone;
    
    // 限制用户每分钟获取验证码频率,如一分钟不能超过3次
    $expire = 10;
    
    // expire重复设置,会覆盖上一次过期时间
    /*$total = $redis->incr($key);
    $redis->expire($key, $expire);
    var_dump($total);*/
    
    // 不让key覆盖
    /*$res = $redis->get($key);
    if ($res) {
        $total = $redis->incr($key);
    } else {
        $res = $redis->setex($key, $expire, 1);
        $total = 1;
    }
    if ($total <= 3) {
        var_dump('send success');
    } else {
        var_dump('send limit');
    }*/
    
    // 进阶
    // setnx: 若key已存在,重复设置会失败
    /*$res = $redis->setnx($key, 1);
    if ($res) {
        $redis->expire($key, $expire);
        $total = 1;
    } else {
        $total = $redis->incr($key);
    }
    if ($total <= 3) {
        var_dump('send success');
    } else {
        var_dump('send limit');
    }*/
    
    // 进阶2
    $res = $redis->set($key, 1, ['ex' => $expire, 'nx']);
    if ($res) {
        $total = 1;
    } else {
        $total = $redis->incr($key);
    }
    var_dump($total);
    if ($total <= 3) {
        var_dump('send success');
    } else {
        var_dump('send limit');
    }

    场景2: 限制一个ip地址不能1秒内访问超过n次(方法同场景1)

    场景3:限制一个人1分钟内点赞/投票次数不能超过n(方法同场景1)

    推荐相关精品课程: redis基础&实战教程

  • redis共享session, 登录态

    通过redis来实现分布式session共享,共享用户登录态

    <?php
    
    require_once '../../CacheRedis.php';
    
    $server = '127.0.0.1:6379';
    $redis = CacheRedis::getInstance($server);
    
    // 共享session
    $keyPrefix = 'login:uid:';
    $id = 19;
    $key = $keyPrefix . $id;
    $sessionExpire = 3600;
    
    // 1. 登录,设置session
    
    // db获取用户信息
    $userInfo = [
        'name' => 'ethan',
        'email' => '11@qq.com'
    ];
    
    // 种session缓存
    $rand1 = rand(10000000, 99999999); // 生成一个随机数
    $rand2 = rand(10000000, 99999999);
    $cookie = md5(sprintf("%d_%d_%d_%d", $id, $rand1, $rand2, time()));
    $res = $redis->setex($cookie, $sessionExpire, json_encode($userInfo));
    
    // 种浏览器cookie
    $cookieExpire = time() + $sessionExpire;
    $domain = '.baidu.com';
    setcookie('LOGIN', $cookie, $cookieExpire, '/', $domain);
    
    // 2. 判断登录态
    
    // 从浏览器获取cookie  php: $cookie = $_COOKIE['LOGIN']
    $cookieNow = $cookie;
    
    // $userInfo非空,已登录状态, 如果为空,跳转登录页
    $userInfo = $redis->get($cookieNow);
    
    // 3. 登出
    
    // 清session缓存
    $res = $redis->del($cookie);
    
    // 清cookie
    setcookie('LOGIN', "", time() - 86400, '/', $domain);
    
    // 扩展 不同服务器,甚至是不同的业务方,都能够共享数据

    推荐相关精品课程: redis基础&实战教程

  • redis计数器使用

    redis计数器常见的使用场景

    <?php
    
    require_once '../../CacheRedis.php';
    
    $server = '127.0.0.1:6379';
    $redis = CacheRedis::getInstance($server);
    
    // 简单计数
    
    // 视频播放量
    $keyPrefix = 'video:play:count:';
    $videoId = 12;
    $key = $keyPrefix . $videoId;
    //$total = $redis->incr($key);
    //var_dump($total);
    
    // 页面访问量
    $key2 = 'request:total';
    //$total2 = $redis->incr($key2);
    //var_dump($total2);
    
    // 投票量,点赞量等等
    
    // 按月/天/小时计数
    $key3 = 'request:total:' . date("Ymd");
    //var_dump($key3);
    //$total3 = $redis->incr($key3);
    //$res = $redis->expire($key3, 3600 * 24 * 2);
    //var_dump($total3);
    
    // 存db
    //$total = $redis->get($key);
    //var_dump($total);
    // 写db
    
    // 补充
    $key4 = 'ps';
    $total = $redis->incrBy($key4, 2);
    var_dump($total);
    
    //$total = $redis->decr($key4);
    //var_dump($total);
    
    //$total = $redis->decrBy($key4, 2);
    //var_dump($total);

    推荐相关精品课程: redis基础&实战教程

  • redis缓存减少数据库压力

    利用redis缓存减少数据库压力的常规流程

    流程1: 读/种缓存

    <?php
    
    require_once '../../CacheRedis.php';
    
    $server = '127.0.0.1:6379';
    $redis = CacheRedis::getInstance($server);
    
    $expire = 3600; // 1h
    $key_prefix = 'goods:';
    
    // 常规使用流程
    
    // step1: 接受参数
    $id = 15;
    
    // step2: 读redis
    $key = $key_prefix . $id;
    $info = $redis->get($key);
    if (!empty($info)) {
        $info = json_decode($info, true);
        echo 'get from redis' . PHP_EOL;
        var_dump($info);
        return $info;
    }
    
    // step3: 读db
    $info = [
        'id' => 15,
        'name' => '商品3',
        'price' => 29
    ];
    
    // step4: 写redis, 种缓存
    $res = $redis->setex($key, $expire, json_encode($info));
    
    // step5: 返回
    echo 'get from db' . PHP_EOL;
    var_dump($info);
    return $info;
    

    流程2: 清缓存

    <?php
    
    require_once '../../CacheRedis.php';
    
    $server = '127.0.0.1:6379';
    $redis = CacheRedis::getInstance($server);
    
    $key_prefix = 'goods:';
    
    // step1: 改db
    
    // step2: 清缓存
    
    $id = 15;
    $key = $key_prefix . $id;
    $res = $redis->del($key);
    
    $info = $redis->get($key);
    var_dump($info);
    

    推荐相关精品课程: redis基础&实战教程

  • redis简单单例

    redis实例化单例类

    class CacheRedis
    {
        private static $_instance = null;
    
        private function __construct() {
        }
    
        /**
         * @param $server
         * @return null|\Redis
         */
        public static function getInstance($server) {
            if (is_null(self::$_instance)) {
                self::$_instance = new \Redis();
                list($host, $port) = explode(':', $server);
                self::$_instance->connect($host, $port);
            }
            return self::$_instance;
        }
    
        private function __clone() {
        }
    }

    推荐相关精品课程: redis基础&实战教程

  • mysql insert select

    日常记录,mysql insert select写法:

    insert into table_a (audit_id,command_no,cid) select audit_id,command_no,id from spamcenter.table_b;
  • 经验: 代码部署,cron脚本执行结果还是老代码问题

    今天遇到一个问题,因为运维相关的需求,需要停写线上的某个服务,代码里全部都做了停写,但代码上线部署后,问题出现了:

    竟然还有数据往服务里写!

    这就比较玄幻了,查了下所有的代码,发现该停的地方确实都停了,为什么呢?

    最终经排查,确定原因:

    cron脚本执行时,会将代码拉入内存,执行期间,读的都是内存中的代码,此时如果你更新了代码,但cron执行的实际还是老的代码,直至脚本执行完毕下一次再次启动才会执行新代码。

    同理,一些daemon脚本服务也是一样的道理,上完代码后,需要手动kill重新启动才可以。

  • imovie导出高清视频(1080p,4k)

    imove可以说是目前mac上使用最为广泛的免费的视频制作工具,但同时也有不少问题会造成困扰。

    经常会遇到,明明自己的原视频是1080p或4k的,但imovie导出时,却仅能导出720p的视频,这种情况可以通过用下面的方法处理。

    imovie导出时可选的分辨率是根据时间轴第一个插入的视频的分辨率决定的,如何看出当前imovie识别出的清晰度呢?可以直接通过下方这个位置看到:

    那么具体如何做呢?

    很简单,首先从网上下载一个4k 或 1080p的小视频,将其拖到时间轴里,这时再看下,就会发现,imovie已经标识4k 或 1080p了。

    如果没有变的话,可能就是你时间轴里已经有了其他非4k/1080p的视频,这时,你可以将已有内容剪切,此时时间轴是空的,将下载的视频拖入时间轴,然后再将剪切的视频粘贴到时间轴就可以了。

    此时,imovie已经认为4k/1080p的视频了,这个时候,只需要再将时间轴里导入的下载的4k/1080p小视频删除即可,接下来就可以导出4k/1080p的视频啦!

    附带: 这下面是两个找到的比较小的4k和1080p视频,大家可以直接下载使用,也可以自己网上搜索下载

    4k: https://cdn1.videvo.net/videvo_files/video/free/2019-12/originalContent/190915_A_04_Drone_15.mp4

    1080p: https://cdn1.videvo.net/videvo_files/video/free/2018-12/originalContent/180607_A_099.mp4

  • WordPress整站迁移

    WordPress进行迁移是一个常遇到的问题,无论是换服务器,换域名等等,可能都会需要对Wordpress进行整站迁移,下面介绍一种简洁高效的迁移方式。

    步骤一: 安装插件 All-in-One WP Migration

    新建一个空白的wordpress站点,在新站点以及待迁移数据的站点上,都安装插件 All-in-One WP Migration

    步骤二: 导出老站点数据

    步骤三: 新站点导入数据

    ps: 默认有最大上传文件限制,如果待导入的文件大小超过该限制,则是无法直接导入的,请看补充步骤。

    补充步骤: 解决上传文件大小限制

    下载Wordpress插件 https://import.wp-migration.com/ , 将插件上传到wp-content/plugins文件夹下:

    此时,进入新站点后台插件管理,就可以看到该插件了,启用该插件:

    此时,再次进行导入,就可以发现上传文件大小的限制已经放大了:

    此时,导入老站点导出的文件后,就完成了整个站点数据的迁移工作。

    最后,将安装的两个插件禁用并删除,all-in-one-wp-migration-file-extension 可能后台直接删除会报错,若报错,直接到服务器上将该文件夹删除即可。