Jelajahi Sumber

tnb update open api

reghao 1 bulan lalu
induk
melakukan
91f696dd55

+ 21 - 21
common/src/main/java/cn/reghao/tnb/common/web/WebResult.java

@@ -64,53 +64,53 @@ public class WebResult<T> {
     }
 
     public static <T> String result(Result result) {
-        WebResult<T> webBody = new WebResult<>(result.getCode(), result.getMsg());
-        return JsonConverter.objectToJson(webBody);
+        WebResult<T> webResult = new WebResult<>(result.getCode(), result.getMsg());
+        return JsonConverter.objectToJson(webResult);
     }
 
     public static <T> String success() {
-        WebResult<T> webBody = new WebResult<>(ResultStatus.SUCCESS.getCode(), ResultStatus.SUCCESS.getMsg());
-        return JsonConverter.objectToJson(webBody);
+        WebResult<T> webResult = new WebResult<>(ResultStatus.SUCCESS.getCode(), ResultStatus.SUCCESS.getMsg());
+        return JsonConverter.objectToJson(webResult);
     }
 
     public static <T> String successWithMsg(String msg) {
-        WebResult<T> webBody = new WebResult<>(ResultStatus.SUCCESS.getCode(), msg);
-        return JsonConverter.objectToJson(webBody);
+        WebResult<T> webResult = new WebResult<>(ResultStatus.SUCCESS.getCode(), msg);
+        return JsonConverter.objectToJson(webResult);
     }
 
     public static <T> String success(T data) {
-        WebResult<T> webBody = new WebResult<>(ResultStatus.SUCCESS.getCode(), ResultStatus.SUCCESS.getMsg());
-        webBody.setData(data);
-        return JsonConverter.objectToJson(webBody);
+        WebResult<T> webResult = new WebResult<>(ResultStatus.SUCCESS.getCode(), ResultStatus.SUCCESS.getMsg());
+        webResult.setData(data);
+        return JsonConverter.objectToJson(webResult);
     }
 
     public static <T> String fail() {
-        WebResult<T> webBody = new WebResult<>(ResultStatus.FAIL.getCode(), ResultStatus.FAIL.getMsg());
-        return JsonConverter.objectToJson(webBody);
+        WebResult<T> webResult = new WebResult<>(ResultStatus.FAIL.getCode(), ResultStatus.FAIL.getMsg());
+        return JsonConverter.objectToJson(webResult);
     }
 
     public static <T> String failWithMsg(String msg) {
-        WebResult<T> webBody = new WebResult<>(ResultStatus.FAIL.getCode(), msg);
-        return JsonConverter.objectToJson(webBody);
+        WebResult<T> webResult = new WebResult<>(ResultStatus.FAIL.getCode(), msg);
+        return JsonConverter.objectToJson(webResult);
     }
 
     public static <T> String notFound() {
-        WebResult<T> webBody = new WebResult<>(ResultStatus.NOTFOUND);
-        return JsonConverter.objectToJson(webBody);
+        WebResult<T> webResult = new WebResult<>(ResultStatus.NOTFOUND);
+        return JsonConverter.objectToJson(webResult);
     }
 
     public static <T> String error() {
-        WebResult<T> webBody = new WebResult<>(ResultStatus.ERROR.getCode(), ResultStatus.ERROR.getMsg());
-        return JsonConverter.objectToJson(webBody);
+        WebResult<T> webResult = new WebResult<>(ResultStatus.ERROR.getCode(), ResultStatus.ERROR.getMsg());
+        return JsonConverter.objectToJson(webResult);
     }
 
     public static <T> String errorWithMsg(String msg) {
-        WebResult<T> webBody = new WebResult<>(ResultStatus.ERROR.getCode(), msg);
-        return JsonConverter.objectToJson(webBody);
+        WebResult<T> webResult = new WebResult<>(ResultStatus.ERROR.getCode(), msg);
+        return JsonConverter.objectToJson(webResult);
     }
 
     public static <T> String fallback(String msg) {
-        WebResult<T> webBody = new WebResult<>(msg);
-        return JsonConverter.objectToJson(webBody);
+        WebResult<T> webResult = new WebResult<>(msg);
+        return JsonConverter.objectToJson(webResult);
     }
 }

+ 16 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/controller/OpenVodController.java

@@ -4,7 +4,9 @@ import cn.reghao.jutil.jdk.web.result.Result;
 import cn.reghao.tnb.common.auth.AuthUser;
 import cn.reghao.tnb.common.web.WebResult;
 import cn.reghao.tnb.content.api.dto.VideoFilePublish;
+import cn.reghao.tnb.content.api.dto.VideoFileUpdate;
 import cn.reghao.tnb.content.api.dto.VideoPublishSbt;
+import cn.reghao.tnb.content.app.vod.model.dto.VideoCoverUpdate;
 import cn.reghao.tnb.content.app.vod.service.VideoPostService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -43,4 +45,18 @@ public class OpenVodController {
         Result result = videoPostService.publishVideoPost(videoPublishSbt);
         return WebResult.result(result);
     }
+
+    @Operation(summary = "修改视频稿件封面", description = "N")
+    @PostMapping("/update_cover")
+    public String updateVideoCover(@RequestBody @Validated VideoCoverUpdate videoCoverUpdate) {
+        videoPostService.updateVideoCover(videoCoverUpdate);
+        return WebResult.success();
+    }
+
+    @Operation(summary = "修改视频稿件文件", description = "N")
+    @PostMapping("/update_file")
+    public String updateVideoFile(@RequestBody @Validated VideoFileUpdate videoFileUpdate) {
+        videoPostService.updateVideoFile(videoFileUpdate);
+        return WebResult.success();
+    }
 }

+ 1 - 1
file/file-service/src/main/java/cn/reghao/tnb/file/app/controller/AvatarController.java

@@ -33,7 +33,7 @@ public class AvatarController {
 
     @Operation(summary = "更新账号头像", description = "N")
     @PostMapping(value = "/update", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String updateUserAvatar(@RequestBody @Validated AvatarUpdate avatarUpdate) throws Exception {
+    public String updateUserAvatar(@RequestBody @Validated AvatarUpdate avatarUpdate) {
         Result result = avatarService.updateAvatar(avatarUpdate);
         if (result.getCode() == ResultStatus.FAIL.getCode()) {
             return WebResult.result(result);

+ 21 - 1
file/file-service/src/main/java/cn/reghao/tnb/file/app/controller/OpenFileController.java

@@ -1,5 +1,7 @@
 package cn.reghao.tnb.file.app.controller;
 
+import cn.reghao.jutil.jdk.web.result.Result;
+import cn.reghao.jutil.jdk.web.result.ResultStatus;
 import cn.reghao.oss.api.dto.ServerInfo;
 import cn.reghao.oss.api.dto.rest.UploadFileRet;
 import cn.reghao.oss.api.dto.rest.UploadPrepare;
@@ -8,6 +10,8 @@ import cn.reghao.oss.api.dto.rest.UploadSample;
 import cn.reghao.tnb.common.auth.AuthUser;
 import cn.reghao.tnb.common.web.WebResult;
 import cn.reghao.oss.api.constant.UploadChannelType;
+import cn.reghao.tnb.file.app.model.dto.AvatarUpdate;
+import cn.reghao.tnb.file.app.service.AvatarService;
 import cn.reghao.tnb.file.app.service.OssUploadService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -18,6 +22,8 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.Map;
+
 /**
  * @author reghao
  * @date 2026-05-18 14:44:51
@@ -28,9 +34,11 @@ import org.springframework.web.bind.annotation.RestController;
 @AuthUser
 public class OpenFileController {
     private final OssUploadService ossUploadService;
+    private final AvatarService avatarService;
 
-    public OpenFileController(OssUploadService ossUploadService) {
+    public OpenFileController(OssUploadService ossUploadService, AvatarService avatarService) {
         this.ossUploadService = ossUploadService;
+        this.avatarService = avatarService;
     }
 
     @Operation(summary = "获取图片上传 token", description = "N")
@@ -83,4 +91,16 @@ public class OpenFileController {
         UploadFileRet uploadFileRet = ossUploadService.checkSample(uploadSample);
         return WebResult.success(uploadFileRet);
     }
+
+    @Operation(summary = "更新账号头像", description = "N")
+    @PostMapping(value = "/update_avatar", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String updateUserAvatar(@RequestBody @Validated AvatarUpdate avatarUpdate) {
+        Result result = avatarService.updateAvatar(avatarUpdate);
+        if (result.getCode() == ResultStatus.FAIL.getCode()) {
+            return WebResult.result(result);
+        }
+
+        String avatarUrl = result.getData();
+        return WebResult.success(avatarUrl);
+    }
 }

+ 2 - 3
file/file-service/src/main/java/cn/reghao/tnb/file/app/model/dto/AvatarUpdate.java

@@ -1,12 +1,12 @@
 package cn.reghao.tnb.file.app.model.dto;
 
+import jakarta.validation.constraints.Size;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
 
 import jakarta.validation.constraints.NotBlank;
-import jakarta.validation.constraints.NotNull;
 
 /**
  * @author reghao
@@ -17,8 +17,7 @@ import jakarta.validation.constraints.NotNull;
 @Setter
 @Getter
 public class AvatarUpdate {
-    @NotNull
-    private Integer channelCode;
     @NotBlank
+    @Size(min = 1, max = 64)
     private String uploadId;
 }

+ 1 - 1
file/file-service/src/main/java/cn/reghao/tnb/file/app/service/AvatarService.java

@@ -24,7 +24,7 @@ public class AvatarService {
         this.ossService = ossService;
     }
 
-    public Result updateAvatar(AvatarUpdate avatarUpdate) throws Exception {
+    public Result updateAvatar(AvatarUpdate avatarUpdate) {
         String uploadId = avatarUpdate.getUploadId();
         ObjectMeta objectMeta = ossService.getObjectMeta(uploadId);
         if (objectMeta != null) {

+ 178 - 110
file/file-service/src/main/java/cn/reghao/tnb/file/app/zjob/BiliOpenApiClient.java → file/file-service/src/main/java/cn/reghao/tnb/file/app/service/OpenApiClient.java

@@ -1,17 +1,18 @@
-package cn.reghao.tnb.file.app.zjob;
+package cn.reghao.tnb.file.app.service;
 
 import cn.reghao.jutil.jdk.converter.DateTimeConverter;
 import cn.reghao.jutil.jdk.io.FileSplitter;
+import cn.reghao.jutil.jdk.media.FFmpegWrapper;
+import cn.reghao.jutil.jdk.media.model.MediaProps;
+import cn.reghao.jutil.jdk.media.model.VideoProps;
 import cn.reghao.jutil.jdk.serializer.JsonConverter;
 import cn.reghao.jutil.jdk.web.result.WebResult;
 import cn.reghao.oss.api.dto.ServerInfo;
 import cn.reghao.oss.api.dto.UploadFilePart;
-import cn.reghao.oss.api.dto.WebBody;
 import cn.reghao.oss.api.dto.rest.UploadFileRet;
 import cn.reghao.oss.api.dto.rest.UploadPrepare;
 import cn.reghao.oss.api.dto.rest.UploadPrepareRet;
 import cn.reghao.oss.api.dto.rest.UploadSample;
-import cn.reghao.oss.api.util.OssClientSigner;
 import cn.reghao.oss.api.util.OssSamplingHash;
 import cn.reghao.oss.sdk.MultiPartBodyPublisher;
 import com.google.gson.reflect.TypeToken;
@@ -35,7 +36,7 @@ import java.util.*;
  * @author reghao
  * @date 2026-05-18 10:48:34
  */
-public class BiliOpenApiClient {
+public class OpenApiClient {
     // 10MB
     private final FileSplitter fileSplitter = new FileSplitter();
     private final String baseUrl;
@@ -43,7 +44,7 @@ public class BiliOpenApiClient {
     private final String secretKey;
     private final HttpClient httpClient;
 
-    public BiliOpenApiClient(String baseUrl, String accessKey, String secretKey) {
+    public OpenApiClient(String baseUrl, String accessKey, String secretKey) {
         this.baseUrl = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl;
         this.accessKey = accessKey;
         this.secretKey = secretKey;
@@ -55,7 +56,55 @@ public class BiliOpenApiClient {
                 .build();
     }
 
-    public UploadPrepareRet prepareUpload(int channelCode, Path filePath) throws Exception {
+    /**
+     * 计算 HMAC-SHA256 签名
+     */
+    private String calculateSign(String sk, String method, String path, String timestamp, String nonce) {
+        String baseString = method + "\n" + path + "\n" + timestamp + "\n" + nonce;
+        return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, sk).hmacHex(baseString);
+    }
+
+    private HttpRequest getPostRequest(String path, String jsonBody) {
+        //String path = "/api/open/content/vod/publish";
+        String timestamp = String.valueOf(System.currentTimeMillis());
+        String nonce = UUID.randomUUID().toString();
+        String method = "POST";
+        String sign = calculateSign(this.secretKey, method, path, timestamp, nonce);
+
+        String url = this.baseUrl + path;
+        return HttpRequest.newBuilder()
+                .uri(URI.create(url))
+                .timeout(Duration.ofSeconds(5)) // 请求超时
+                .header("Content-Type", "application/json; charset=UTF-8")
+                .header("X-AK", this.accessKey)
+                .header("X-Timestamp", timestamp)
+                .header("X-Nonce", nonce)
+                .header("X-Sign", sign)
+                .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
+                .build();
+    }
+
+    private ServerInfo getServerInfo(String channel) throws IOException, InterruptedException {
+        Map<String, Object> map = new HashMap<>();
+        String jsonBody = JsonConverter.objectToJson(map);
+
+        String path = String.format("/api/open/file/serverinfo/%s", channel);
+        HttpRequest request = getPostRequest(path, jsonBody);
+        // 5. 发送请求并获取响应
+        // 如果在外层用虚拟线程(Thread.ofVirtual().start(...))调用此方法,此处的 send() 阻塞将不会占用真实物理线程!
+        HttpResponse<String> response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+        // 6. 处理响应状态码
+        if (response.statusCode() == 200) {
+            String body = response.body();
+            Type type = new TypeToken<WebResult<ServerInfo>>(){}.getType();
+            WebResult<ServerInfo> webResult = JsonConverter.jsonToObject(body, type);
+            return webResult.getData();
+        } else {
+            throw new RuntimeException("Status Code: " + response.statusCode() + ", Response: " + response.body());
+        }
+    }
+
+    private UploadPrepareRet prepareUpload(int channelCode, Path filePath) throws Exception {
         // 1. 计算 SHA-256 (用于后端秒传校验)
         String sha256 = OssSamplingHash.calculateFullHash(filePath);
         String filename0 = filePath.getFileName().toString();
@@ -78,7 +127,7 @@ public class BiliOpenApiClient {
         return uploadPrepareRet;
     }
 
-    public UploadFileRet checkSample(Path filePath, UploadPrepareRet uploadPrepareRet) throws Exception {
+    private UploadFileRet checkSample(Path filePath, UploadPrepareRet uploadPrepareRet) throws Exception {
         String uploadId = uploadPrepareRet.getUploadId();
         long offset = uploadPrepareRet.getOffset();
         int length = uploadPrepareRet.getLength();
@@ -101,7 +150,7 @@ public class BiliOpenApiClient {
         return uploadFileRet;
     }
 
-    public UploadFileRet uploadFilePart(int channelCode, String uploadUrl, String token, Path filePath) throws Exception {
+    private UploadFileRet uploadFilePart(int channelCode, String uploadUrl, String token, Path filePath) throws Exception {
         UploadPrepareRet uploadPrepareRet = prepareUpload(channelCode, filePath);
         if (uploadPrepareRet.isExist()) {
             UploadFileRet uploadFileRet = checkSample(filePath, uploadPrepareRet);
@@ -134,7 +183,7 @@ public class BiliOpenApiClient {
             map.put(chunkNumber, start);
 
             int currentChunkSize = part.length;
-            UploadFilePart uploadFilePart = new UploadFilePart(101, identifier, filename, relativePath,
+            UploadFilePart uploadFilePart = new UploadFilePart(channelCode, identifier, filename, relativePath,
                     totalSize, chunkSize, totalChunks, chunkNumber, currentChunkSize);
 
             UploadFileRet uploadFileRet = postObject(uploadUrl, token, part, uploadFilePart);
@@ -176,10 +225,10 @@ public class BiliOpenApiClient {
         int statusCode = httpResponse.statusCode();
         if (statusCode == 200) {
             String body = httpResponse.body();
-            Type type = new TypeToken<WebBody>(){}.getType();
-            WebBody webBody = JsonConverter.jsonToObject(body, type);
-            if (webBody.getCode() == 0 ) {
-                return webBody.getUploadFileRet();
+            Type type = new TypeToken<WebResult<UploadFileRet>>(){}.getType();
+            WebResult<UploadFileRet>  webResult = JsonConverter.jsonToObject(body, type);
+            if (webResult.getCode() == 0 ) {
+                return webResult.getData();
             }
         }
         return null;
@@ -222,133 +271,152 @@ public class BiliOpenApiClient {
         return null;
     }
 
-    public String publishVideoFile(Map<String, Object> map) throws Exception {
-        String jsonBody = JsonConverter.objectToJson(map);
-
-        String path = "/api/open/content/vod/publish/file";
+    private String postRequest(String path, Map<String, Object> body) {
+        String jsonBody = JsonConverter.objectToJson(body);
         HttpRequest request = getPostRequest(path, jsonBody);
-        HttpResponse<String> response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
-        if (response.statusCode() == 200) {
-            String body = response.body();
-            Type type = new TypeToken<WebResult<String>>(){}.getType();
-            WebResult<String> webResult = JsonConverter.jsonToObject(body, type);
-            if (webResult.getCode() == 0) {
-                return webResult.getData();
+        try {
+            HttpResponse<String> response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
+            if (response.statusCode() != 200) {
+                throw new RuntimeException("Status Code: " + response.statusCode() + ", Response: " + response.body());
             }
-        }
 
-        throw new RuntimeException("API Request Failed! Status Code: " + response.statusCode() + ", Response: " + response.body());
+            return response.body();
+        } catch (IOException | InterruptedException e) {
+            throw new RuntimeException(e);
+        }
     }
 
-    public String publishVideoPost(Map<String, Object> map) throws Exception {
-        String jsonBody = JsonConverter.objectToJson(map);
+    public void updateAvatar(File avatarFile) throws Exception {
+        ServerInfo serverInfo1 = getServerInfo("image");
+        UploadFileRet uploadFileRet1 = uploadSingleFile(serverInfo1.getOssUrl(), serverInfo1.getToken(), Path.of(avatarFile.getPath()));
+        String  avatarFileId = uploadFileRet1.getUploadId();
 
-        String path = "/api/open/content/vod/publish/post";
-        HttpRequest request = getPostRequest(path, jsonBody);
-        // 5. 发送请求并获取响应
-        // 如果在外层用虚拟线程(Thread.ofVirtual().start(...))调用此方法,此处的 send() 阻塞将不会占用真实物理线程!
-        HttpResponse<String> response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
-        // 6. 处理响应状态码
-        if (response.statusCode() == 200) {
-            String body = response.body();
-            Type type = new TypeToken<WebResult<String>>(){}.getType();
-            WebResult<String> webResult = JsonConverter.jsonToObject(body, type);
-            if (webResult.getCode() == 0) {
-                return webResult.getData();
-            }
-        }
+        String path = "/api/open/file/update_avatar";
+        Map<String, Object> map = new HashMap<>();
+        map.put("uploadId", avatarFileId);
 
-        throw new RuntimeException("API Request Failed! Status Code: " + response.statusCode() + ", Response: " + response.body());
+        String body = postRequest(path, map);
+        Type type = new TypeToken<WebResult<String>>(){}.getType();
+        WebResult<String> webResult = JsonConverter.jsonToObject(body, type);
+        if (webResult.getCode() != 0) {
+            throw new RuntimeException("post failed: " + webResult.getMsg());
+        }
     }
 
-    public void updateAvatar() {
-    }
+    public void publishVideoPost(File coverFile, File videoFile) throws Exception {
+        if (coverFile == null) {
+            coverFile = new File(getCoverPath(videoFile));
+        }
 
-    public void updateVideoCover() {
+        ServerInfo serverInfo1 = getServerInfo("image");
+        UploadFileRet uploadFileRet1 = uploadSingleFile(serverInfo1.getOssUrl(), serverInfo1.getToken(), Path.of(coverFile.getPath()));
+        String coverFileId = uploadFileRet1.getUploadId();
+
+        ServerInfo serverInfo2 = getServerInfo("video");
+        int channelCode = serverInfo2.getChannelCode();
+        UploadFileRet uploadFileRet2 = uploadFilePart(channelCode, serverInfo2.getOssUrl(), serverInfo2.getToken(), Path.of(videoFile.getPath()));
+        String videoFileId = uploadFileRet2.getUploadId();
+        Map<String, Object> map0 = new HashMap<>();
+        map0.put("videoFileId", videoFileId);
+        map0.put("channelCode", 101);
+        map0.put("filename", videoFile.getName());
+
+        String path0 = "/api/open/content/vod/publish/file";
+        String body = postRequest(path0, map0);
+        Type type = new TypeToken<WebResult<String>>(){}.getType();
+        WebResult<String> webResult = JsonConverter.jsonToObject(body, type);
+        if (webResult.getCode() != 0) {
+            throw new RuntimeException("post failed: " + webResult.getMsg());
+        }
+        String videoId = webResult.getData();
+
+        String title = DateTimeConverter.format(LocalDateTime.now());
+        Map<String, Object> map1 = new HashMap<>();
+        map1.put("videoId", videoId);
+        map1.put("coverFileId", coverFileId);
+        map1.put("title", title);
+        map1.put("description", videoFile.getName());
+        map1.put("categoryPid", 11);
+        map1.put("categoryId", 12);
+        map1.put("tags", List.of("tnb"));
+        map1.put("scope", 2);
+
+        String path1 = "/api/open/content/vod/publish/post";
+        String body1 = postRequest(path1, map1);
+        Type type1 = new TypeToken<WebResult<String>>(){}.getType();
+        WebResult<String> webResult1 = JsonConverter.jsonToObject(body1, type1);
+        if (webResult1.getCode() != 0) {
+            throw new RuntimeException("post failed: " + webResult.getMsg());
+        }
     }
 
-    public void updateVideoFile() {
+    private String getCoverPath(File videoFile) {
+        return "";
     }
 
-    private HttpRequest getPostRequest(String path, String jsonBody) {
-        //String path = "/api/open/content/vod/publish";
-        String timestamp = String.valueOf(System.currentTimeMillis());
-        String nonce = UUID.randomUUID().toString();
-        String method = "POST";
-        String sign = calculateSign(this.secretKey, method, path, timestamp, nonce);
+    public void updateVideoCover(String videoId, File coverFile) throws Exception {
+        ServerInfo serverInfo1 = getServerInfo("image");
+        UploadFileRet uploadFileRet1 = uploadSingleFile(serverInfo1.getOssUrl(), serverInfo1.getToken(), Path.of(coverFile.getPath()));
+        String  coverFileId = uploadFileRet1.getUploadId();
 
-        String url = this.baseUrl + path;
-        return HttpRequest.newBuilder()
-                .uri(URI.create(url))
-                .timeout(Duration.ofSeconds(5)) // 请求超时
-                .header("Content-Type", "application/json; charset=UTF-8")
-                .header("X-AK", this.accessKey)
-                .header("X-Timestamp", timestamp)
-                .header("X-Nonce", nonce)
-                .header("X-Sign", sign)
-                .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
-                .build();
-    }
+        String path = "/api/open/content/vod/update_cover";
+        Map<String, Object> map = new HashMap<>();
+        map.put("videoId", videoId);
+        map.put("coverFileId", coverFileId);
 
-    /**
-     * 计算 HMAC-SHA256 签名
-     */
-    private String calculateSign(String sk, String method, String path, String timestamp, String nonce) {
-        String baseString = method + "\n" + path + "\n" + timestamp + "\n" + nonce;
-        return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, sk).hmacHex(baseString);
+        String body = postRequest(path, map);
+        Type type = new TypeToken<WebResult<String>>(){}.getType();
+        WebResult<String> webResult = JsonConverter.jsonToObject(body, type);
+        if (webResult.getCode() != 0) {
+            throw new RuntimeException("post failed: " + webResult.getMsg());
+        }
     }
 
-    public ServerInfo getServerInfo(String channel) throws IOException, InterruptedException {
+    public void updateVideoFile(String videoId, File videoFile) throws Exception {
+        ServerInfo serverInfo2 = getServerInfo("video");
+        UploadFileRet uploadFileRet2 = uploadFilePart(101, serverInfo2.getOssUrl(), serverInfo2.getToken(), Path.of(videoFile.getPath()));
+        String videoFileId = uploadFileRet2.getUploadId();
+
+        String path = "/api/open/content/vod/update_video";
         Map<String, Object> map = new HashMap<>();
-        String jsonBody = JsonConverter.objectToJson(map);
+        map.put("videoId", videoId);
+        map.put("videoFileId", videoFileId);
 
-        String path = String.format("/api/open/file/serverinfo/%s", channel);
-        HttpRequest request = getPostRequest(path, jsonBody);
-        // 5. 发送请求并获取响应
-        // 如果在外层用虚拟线程(Thread.ofVirtual().start(...))调用此方法,此处的 send() 阻塞将不会占用真实物理线程!
-        HttpResponse<String> response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
-        // 6. 处理响应状态码
-        if (response.statusCode() == 200) {
-            String body = response.body();
-            Type type = new TypeToken<WebResult<ServerInfo>>(){}.getType();
-            WebResult<ServerInfo> webResult = JsonConverter.jsonToObject(body, type);
-            return webResult.getData();
-        } else {
-            throw new RuntimeException("API Request Failed! Status Code: " + response.statusCode() + ", Response: " + response.body());
+        String body = postRequest(path, map);
+        Type type = new TypeToken<WebResult<String>>(){}.getType();
+        WebResult<String> webResult = JsonConverter.jsonToObject(body, type);
+        if (webResult.getCode() != 0) {
+            throw new RuntimeException("post failed: " + webResult.getMsg());
         }
     }
 
     public static void main(String[] args) throws Exception {
+        long userId = 11011L;
         String baseUrl = "https://reghao.cn";
         String accessKey = "AK7E622DA20E9B48";
         String secretKey = "SK89E908C80C8747E19B1ED68C7A6CA25D";
-        BiliOpenApiClient biliOpenApiClient = new BiliOpenApiClient(baseUrl, accessKey, secretKey);
+        OpenApiClient openApiClient = new OpenApiClient(baseUrl, accessKey, secretKey);
+
+        File avatarFile = new File("/home/reghao/Downloads/1/avatar.jpg");
+        //openApiClient.updateAvatar(avatarFile);
 
         File coverFile = new File("/home/reghao/Downloads/1/cover.jpg");
-        ServerInfo serverInfo1 = biliOpenApiClient.getServerInfo("image");
-        UploadFileRet uploadFileRet1 = biliOpenApiClient.uploadSingleFile(serverInfo1.getOssUrl(), serverInfo1.getToken(), Path.of(coverFile.getPath()));
-        String coverFileId = uploadFileRet1.getUploadId();
+        coverFile = new File("/home/reghao/Downloads/v2-cb256237a256669399845935ff1d0e06_r.jpg");
+        for (int i = 0; i < 1000; i++) {
+            //openApiClient.updateVideoCover("6KMyx0WvmD", coverFile);
+            //Thread.sleep(1000);
+        }
 
-        File videoFile = new File("/home/reghao/Downloads/1/video.mp4");
-        ServerInfo serverInfo2 = biliOpenApiClient.getServerInfo("video");
-        UploadFileRet uploadFileRet2 = biliOpenApiClient.uploadFilePart(101, serverInfo2.getOssUrl(), serverInfo2.getToken(), Path.of(videoFile.getPath()));
-        String videoFileId = uploadFileRet2.getUploadId();
-        Map<String, Object> map0 = new HashMap<>();
-        map0.put("videoFileId", videoFileId);
-        map0.put("channelCode", 101);
-        map0.put("filename", videoFile.getName());
-        String videoId = biliOpenApiClient.publishVideoFile(map0);
+        File videoFile = new File("/home/reghao/Downloads/26.mkv");
+        //biliOpenApiClient.updateVideoFile("", videoFile);
 
-        String title = DateTimeConverter.format(LocalDateTime.now());
-        Map<String, Object> map = new HashMap<>();
-        map.put("videoId", videoId);
-        map.put("coverFileId", coverFileId);
-        map.put("title", title);
-        map.put("description", videoFile.getName());
-        map.put("categoryPid", 11);
-        map.put("categoryId", 12);
-        map.put("tags", List.of("tnb"));
-        map.put("scope", 2);
-        biliOpenApiClient.publishVideoPost(map);
+        MediaProps mediaProps = FFmpegWrapper.getMediaProps(videoFile.getAbsolutePath());
+        VideoProps videoProps = mediaProps.getVideoProps();
+        if (videoProps != null) {
+            double duration = videoProps.getDuration();
+            System.out.println();
+        }
+
+        //biliOpenApiClient.publishVideoPost(coverFile, videoFile);
     }
 }

+ 1 - 1
pom.xml

@@ -70,7 +70,7 @@
         <dependency>
             <groupId>com.github.reghao.jutil</groupId>
             <artifactId>jdk</artifactId>
-            <version>65a0ede5</version>
+            <version>5425b5d83c</version>
         </dependency>
 
         <dependency>