1. 程式人生 > 其它 >手把手教你做短視訊去水印微信小程式(5-服務端程式碼)

手把手教你做短視訊去水印微信小程式(5-服務端程式碼)

技術標籤:小程式微信開發小程式微信去水印短視訊去水印

手把手教你做短視訊去水印微信小程式(5-服務端程式碼)

文章目錄


前言

前邊幾篇文章我們介紹了小程式端關鍵程式碼,這一篇我們來說一下服務端程式碼。這裡主要藉助一個開源專案 smalls/video-tools 來實現視訊解析的核心部分,在此基礎上,我們實現api介面以供呼叫。


一、框架

這裡我選用我最為熟悉的php語言開發框架:Laravel

目前laravel版本已經到了 8.x,這裡我使用的是長期支援版 6.x

快速開始請見github的 readme.md 文件。

有關框架的使用在此不做介紹,有不熟悉的同學可以查閱官方文件,laravel是值得phper掌握的優雅框架。這裡我們的實際程式碼量相對較小。

二、登陸/退出介面

微信登陸我們使用overtrue大神封裝的composer包:overtrue/laravel-wechat

2.1 路由

routes/api.php 檔案中新增路由:

Route::group(['prefix' => 'auth'
, 'namespace' => 'Auth'], function () { Route::post('login', '[email protected]')->name('login'); Route::post('logout', '[email protected]')->name('logout'); });

2.2 控制器

重寫 App\Http\Controllers\Auth\LoginController 檔案的login方法,使用 overtrue/laravel-wechat

<?php

namespace App\
Http\Controllers\Auth
; use App\Http\Controllers\Controller; use App\Models\User; use App\Providers\RouteServiceProvider; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; use Illuminate\Support\Str; class LoginController extends Controller { /* |-------------------------------------------------------------------------- | Login Controller |-------------------------------------------------------------------------- | | This controller handles authenticating users for the application and | redirecting them to your home screen. The controller uses a trait | to conveniently provide its functionality to your applications. | */ use AuthenticatesUsers; /** * Where to redirect users after login. * * @var string */ protected $redirectTo = RouteServiceProvider::HOME; /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest')->except('logout'); } public function login(Request $request) { $miniProgram = \EasyWeChat::miniProgram(); // 小程式 $sessionInfo = $miniProgram->auth->session($request->input('code')); $decryptedData = $miniProgram->encryptor->decryptData($sessionInfo['session_key'], $request->input('iv'), $request->input('data')); $user = User::firstOrCreate([ 'openid' => $decryptedData['openId'], ],[ 'name' => $decryptedData['nickName'], 'avatar' => $decryptedData['avatarUrl'], 'gender' => $decryptedData['gender'], 'unionid' => $decryptedData['unionId'], 'country' => $decryptedData['country'], 'province' => $decryptedData['province'], 'city' => $decryptedData['city'], ]); $user->api_token = Str::random(80); $user->save(); return response()->json(['token' => $user->api_token]); } }

退出介面沒有進行重寫,logout介面實際呼叫的是sessionGuard的退出邏輯,實際在小程式中也沒有提供退出功能,大家知道就好。

三、視訊解析、解析記錄介面

這邊就不拆開細講了,整段程式碼貼出來,詳細請看註釋。

3.1 路由

routes/api.php 檔案中新增路由:

程式碼如下(示例):

// 以下介面需要識別使用者登陸態,因此新增api認證中介軟體
Route::group(['middleware' => 'auth:api'], function () {
	// 視訊解析介面
    Route::post('video-parse', '[email protected]')->name('video.parse');

	// 當前使用者解析記錄總數
    Route::get('records/total', '[email protected]');
    // 當前使用者解析記錄列表介面
    Route::resource('records', 'RecordController');
});

3.2 控制器

3.2.1 視訊地址解析

我們新建一個視訊地址解析controller:

class VideoParseController extends Controller
{
    public function parse(Request $request)
    {
    	// 引數驗證器
        $request->validate([
            'url' => 'required|string|url', //url引數格式驗證
        ]);

        $user = $request->user();
        $url = $request->input('url');
        Log::info("video-parse|user_id:{$user->id}|{$url}");
        $urlInfo = parse_url($url);
        $host = $urlInfo['host'];

        $domain = implode('.', array_slice(explode('.', $host), -2));
		// 優先嚐試從快取獲取資料(快取有效期3600秒)
        [$noWatermarkUrl, $imageUrl] = Cache::remember(md5($url), 3600, function () use($domain, $url) {
        	// 根據域名判斷短視訊來源
            switch ($domain) {
                //抖音
                case 'douyin.com':
                    $data = VideoManager::DouYin()->start($url);
                    break;
                //微視
                case 'qq.com':
                    $data = VideoManager::WeiShi()->start($url);
                    break;
                //快手
                case 'kuaishou.com':
                case 'chenzhongtech.com':
                    $data = VideoManager::KuaiShou()->start($url);
                    break;
                //最右
                case 'izuiyou.com':
                    $data = VideoManager::ZuiYou()->start($url);
                    break;
                //皮皮蝦
                case 'hulushequ.com':
                case 'pipix.com':
                    $data = VideoManager::PiPiXia()->start($url);
                    break;
                //皮皮搞笑
                case 'ippzone.com':
                    $data = VideoManager::PiPiGaoXiao()->start($url);
                    break;
                default:
                    abort(Response::HTTP_BAD_REQUEST, '解析失敗,請檢查地址');

            }
            // 視訊地址
            $videoUrl = Arr::get($data, 'video_url');
            // 縮圖地址
            $imageUrl = Arr::get($data, 'img_url');
            // 視訊地址為空時直接返回500狀態碼
            abort_if(empty($videoUrl), Response::HTTP_INTERNAL_SERVER_ERROR, '解析失敗,請稍後再試');
            return [preg_replace('/^http:/', 'https:', $videoUrl), $imageUrl];
        });
		
		// 當得到無水印地址後,存入資料庫,用於查閱解析歷史
        if ($noWatermarkUrl) {
            $record = Record::firstOrNew(['url' => $url], [
                'host' => $host,
            ]);
            $record->no_water_mark_url = $noWatermarkUrl;
            $record->image_url = $imageUrl;
            $user->records()->save($record);
            return response()->json([
                'url' => $noWatermarkUrl,
                'image' => $imageUrl,
                'preview' => config('app.preview'), // 這裡注意,這個引數是用來控制視訊是否展示的!由於微信小程式個人主體不能涉及視訊,所以需要服務端控制是否展示,需要稽核通過後再顯示視訊,以達到目的!
            ]);
        } else {
            Cache::forget(md5($url));
            return response()->json(['message' => '轉換失敗,請檢查連結是否有效,或聯絡客服'], Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }
}

這裡注意,返回引數中有一個preview引數,這個引數是用來控制視訊是否展示的!由於微信小程式個人主體不能涉及視訊,所以我們耍個小聰明,通過服務端控制視訊是否展示,這樣我們在小程式稽核通過後再顯示視訊,以達到目的!(請勿濫用)

3.2.2 解析記錄controller

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\Response;

class RecordController extends Controller
{
	// 獲取某使用者歷史解析列表
    public function index(Request $request)
    {
        $data = $request->user()->records()->orderBy('updated_at', 'desc')->paginate($request->input('size', 10))->toArray();
        $data['preview'] = config('app.preview');
        return response()->json($data);
    }

	// 獲取某使用者解析總數
    public function getTotalNum(Request $request)
    {
        $totalNum = $request->user()->records()->count();
        return response()->json([
            'total_num' => $totalNum,
        ]);
    }

	// 刪除某條記錄
    public function destroy($id, Request $request)
    {
        $result = $request->user()->records()->where('id', $id)->delete();
        if ($result) {
            return response()->json([
                'message' => '刪除成功'
            ]);
        } else {
            return response()->json([
                'message' => '刪除失敗'
            ], Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }
}


總結

得益於我們核心程式碼使用了開源專案,我們只做了針對具體業務的封裝,所以整體編碼量相對較小,後續只需共同維護解析部分即可,這便是開源的力量,再次鳴謝:


系列文章

github原始碼地址

在這裡插入圖片描述
歡迎瀏覽,歡迎star~