返回

提问 添加收藏

阿里云oss 上传与获取图片、视频+图片视频内容安全审核

一个点一个点 发布于 2019年05月06日 (共有0个回帖)

1、依赖

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>2.6.0</version>
</dependency>

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>3.3.1</version>
</dependency>

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <systemPath>${lib.path}/aliyun-java-sdk-dysmsapi-1.0.0.jar
    </systemPath>
    <scope>system</scope>
</dependency>

2、Controller

/**
     * 上传视频到阿里云-时长截帧
     * @param file
     * @return
     */
    @ApiOperation(value = "上传视频到阿里云-时长截帧-[内容安全鉴别]")
    @RequestMapping(value = "/filevideo/duration/upload", method = RequestMethod.POST,consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @ApiResponses({
            @ApiResponse(code = 0 ,message = "上传成功"),
            @ApiResponse(code = 1,message = "等待审核"),
            @ApiResponse(code = -1,message = "违法视频"),
            @ApiResponse(code = 500,message = "上传出错,请重新尝试上传")
    })
    public ReturnEntity uploadVideoByDuration(@ApiParam(required = true,value = "表单形式提交的文件") @RequestParam MultipartFile file,Double duration,@ApiIgnore HttpServletRequest request){
        String image= null;
        try {
            image = OSSManageUtil.uploadvideo(file);
            //视频内容安全审核,通过视频截帧检测
            Boolean check = OSSManageUtil.videoContentSecurityByDuration(image,(int)Math.floor(duration));
//            //视频内容安全审核,阿里云返回任务id
//            String  taskId = OSSManageUtil.videoContentSecurity(image);
            //任务id查询视频内容安全解析结果
//            Boolean check = true;
//            Thread.sleep(30000);
//            check= OSSManageUtil.videoParseResult(taskId);
            if(check){
                //内容安全审核通过
                return new ReturnEntity(image);
            }else {
                OSSManageUtil.deleteFileByUrl(new OSSConfig(),image,2);
                return new ReturnEntity(-1,"违法视频");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new ReturnEntity(e);
        }
    }

工具类OSSManageUtil

 

/**
 * 阿里云OSS操作
 */
@Slf4j
public class OSSManageUtil {
   private static OSSConfig ossConfig=OSSConfig.getInstance();

   /**
    * 获首页视频
    * @return
    */
   public static List<String> getVideo() {
      ArrayList<String> imagesList = new ArrayList<>();
      //获取首页视频全部文件
      ArrayList<String> fileListName = GetFileAllContent(OssEnum.VIDEO.getName());
      fileListName.stream().forEach(e ->{
         imagesList.add(ossConfig.getAccessUrlVideo()+"/"+e);
      });
      return imagesList;
   }

   /**
    * 获取media72 文件夹下的所有文件名
    * @param FileName
    * @return
    */
   public static ArrayList<String> GetFileAllContent(String FileName)
   {
      OSSClient ossClient=new OSSClient(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());

      // 构造ListObjectsRequest请求
      ListObjectsRequest listObjectsRequest = new ListObjectsRequest(ossConfig.getBucketNameVideo());
      //Delimiter 设置为 “/” 时,罗列该文件夹下的文件
      listObjectsRequest.setDelimiter("/");
      //Prefix 设为某个文件夹名,罗列以此 Prefix 开头的文件
      listObjectsRequest.setPrefix(FileName);

      ObjectListing listing = ossClient.listObjects(listObjectsRequest);
      ArrayList<String> list = new ArrayList<String>();
      // 遍历所有Object:目录下的文件
      for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
         String key = objectSummary.getKey();
         if(key.equals(FileName)){
            continue;
         }
         list.add(key);
      }
      ossClient.shutdown();
      return list;
   }

   /**
    * 上传OSS服务器文件
    */
   public static String uploadFile(InputStream inputStream) throws IOException {
      String fileName = UUID.randomUUID().toString()+".jpg";
      OSSClient ossClient=new OSSClient(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
      //创建上传Object的Metadata
      ObjectMetadata objectMetadata=new ObjectMetadata();
      objectMetadata.setContentLength(inputStream.available());
      objectMetadata.setContentEncoding("utf-8");
      objectMetadata.setCacheControl("no-cache");
      objectMetadata.setHeader("Pragma", "no-cache");
      objectMetadata.setContentType(contentType(fileName.substring(fileName.lastIndexOf("."))));
      objectMetadata.setContentDisposition("inline;filename=" + fileName);
      //上传文件
      ossClient.putObject(ossConfig.getBucketName(), fileName, inputStream, objectMetadata);
      return ossConfig.getAccessUrl()+"/" +fileName;
   }

   /**
    * 上传图片、文件、视频等到阿里云--指定目录
    * @param file
    * @param type
    * @return
    */
   public static String uploadFile1(MultipartFile file, String type) throws IOException, ClientException {
      StringBuffer fileName = new StringBuffer();
      String fileExtension  = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
      InputStream inputStream =new ByteArrayInputStream(file.getBytes());
if("1".equals(type)){
      //指定目录 如 xx111
      fileName.append(OssEnum.BUSINESS.getName());
   }
   if("2".equals(type)){
      //指定目录 如 xx22
      fileName.append(OssEnum.INSTALLER.getName());
   }
   if("3".equals(type)){
      //指定目录 如 xx3
      fileName.append(OssEnum.USERIMAGE_HEADIMAGE.getName());
   }
fileName.append( UUID.randomUUID().toString()+fileExtension);

      OSSClient ossClient=new OSSClient(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
      //创建上传Object的Metadata
      ObjectMetadata objectMetadata=new ObjectMetadata();
      objectMetadata.setContentLength(inputStream.available());
      objectMetadata.setContentEncoding("utf-8");
      objectMetadata.setCacheControl("no-cache");
      objectMetadata.setHeader("Pragma", "no-cache");
      objectMetadata.setContentType(contentType(fileName.substring(fileName.lastIndexOf(".")+1)));//类型
      objectMetadata.setContentDisposition("inline;filename=" + fileName);//表示能在线播放
      //上传文件
      ossClient.putObject(ossConfig.getBucketName(), fileName.toString(), inputStream, objectMetadata);
      return ossConfig.getAccessUrl()+"/" +fileName;
   }

   /**
    * 图片内容安全审核
    * @param url 图片url地址
    * @return
    * @throws ClientException
    * @throws UnsupportedEncodingException
    */
   public static Boolean contentSecurity(String url,Integer initRate) throws ClientException, UnsupportedEncodingException {
      //请替换成你自己的accessKeyId、accessKeySecret
      IClientProfile profile = DefaultProfile.getProfile(ossConfig.getRegionId(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
      DefaultProfile.addEndpoint(ossConfig.getEndPointName(), ossConfig.getRegionId(), "Green", ossConfig.getDomain());
      IAcsClient client = new DefaultAcsClient(profile);

      ImageSyncScanRequest imageSyncScanRequest = new ImageSyncScanRequest();
      imageSyncScanRequest.setAcceptFormat(FormatType.JSON); // 指定api返回格式
      imageSyncScanRequest.setMethod(com.aliyuncs.http.MethodType.POST); // 指定请求方法
      imageSyncScanRequest.setEncoding("utf-8");
      imageSyncScanRequest.setRegionId(ossConfig.getRegionId());

      List<Map<String, Object>> tasks = new ArrayList<Map<String, Object>>();
      Map<String, Object> task = new LinkedHashMap<String, Object>();
      task.put("dataId", UUID.randomUUID().toString());
      task.put("url", url);
      task.put("time", new Date());

      tasks.add(task);
      JSONObject data = new JSONObject();
      /**
       * porn: 色情
       * terrorism: 暴恐
       * qrcode: 二维码
       * ad: 图片广告
       * ocr: 文字识别
       */
      data.put("scenes", Arrays.asList("porn","terrorism"));
      data.put("tasks", tasks);

      imageSyncScanRequest.setHttpContent(data.toJSONString().getBytes("UTF-8"), "UTF-8", FormatType.JSON);

      /**
       * 请务必设置超时时间
       */
      imageSyncScanRequest.setConnectTimeout(3000);
      imageSyncScanRequest.setReadTimeout(6000);

      try {
         HttpResponse httpResponse = client.doAction(imageSyncScanRequest);

         if (httpResponse.isSuccess()) {
            JSONObject scrResponse = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
            System.out.println(JSON.toJSONString(scrResponse, true));
            if (200 == scrResponse.getInteger("code")) {
               JSONArray taskResults = scrResponse.getJSONArray("data");
               for (Object taskResult : taskResults) {
                  if(200 == ((JSONObject)taskResult).getInteger("code")){
                     JSONArray sceneResults = ((JSONObject)taskResult).getJSONArray("results");
                     Boolean result = true;
                     for (Object sceneResult : sceneResults) {
                        try {
                           String scene = ((JSONObject)sceneResult).getString("scene");
                           String suggestion = ((JSONObject)sceneResult).getString("suggestion");
                           Double rate = ((JSONObject)sceneResult).getDouble("rate");
                           /**
                            * porn: 反色情
                            * terrorism: 反暴恐
                            * qrcode: 二维码
                            * ad: 图片广告
                            * ocr: 文字识别
                            */
                           if ("porn".equals(scene)) {
                              //反色情,true表示合格
                              result = result&&("pass".equals(suggestion) && rate >= initRate);
                           }
                           if("terrorism".equals(scene)){
                              //反暴恐,true表示合格
                              result = result&&("pass".equals(suggestion) && rate >= initRate);
                           }
                        }catch (Exception e){
                           log.error("图片内容安全审核,返回解析信息错误");
                           e.printStackTrace();
                           return false;
                        }
                     }
                     return result;
                  }else{
                     log.error("task process fail:" + ((JSONObject)taskResult).getInteger("code"));
                  }
               }
            } else {
               log.error("detect not success. code:" + scrResponse.getInteger("code"));
            }
         } else {
            log.error("response not success. status:" + httpResponse.getStatus());
         }
      } catch (ServerException e) {
         e.printStackTrace();
      } catch (ClientException e) {
         e.printStackTrace();
      } catch (Exception e){
         e.printStackTrace();
      }
      return false;
   }

   /**
    * 根据key删除OSS服务器上的文件
    */
   public static void deleteFile(OSSConfig ossConfig,String filePath){
      OSSClient ossClient = new OSSClient(ossConfig.getEndpoint(),ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
      ossClient.deleteObject(ossConfig.getBucketName(), filePath);
      
   }

   /**
    * 根据url,删除OSS服务器上的文件
    */
   public static void deleteFileByUrl(OSSConfig ossConfig,String url,Integer type){
      //1表示图片
      if(type == 1){
         deleteFile(ossConfig,url.split(ossConfig.getAccessUrl()+"/")[1]);
      }
      //2表示视频media72
      if(type == 2){
         deleteFile(ossConfig,url.split(ossConfig.getAccessUrlVideo()+"/")[1]);
      }
   }
   
    /**
     * Description: 判断OSS服务文件上传时文件的contentType
     * @Version1.0
     * @param FilenameExtension 文件后缀
     * @return String 
     */
    public static String contentType(String FilenameExtension){
      if(FilenameExtension.equals("BMP")||FilenameExtension.equals("bmp")){return "image/bmp";}
      if(FilenameExtension.equals("GIF")||FilenameExtension.equals("gif")){return "image/gif";}
      if(FilenameExtension.equals("JPEG")||FilenameExtension.equals("jpeg")||
         FilenameExtension.equals("JPG")||FilenameExtension.equals("jpg")||  
         FilenameExtension.equals("PNG")||FilenameExtension.equals("png")){return "image/jpeg";}
      if(FilenameExtension.equals("HTML")||FilenameExtension.equals("html")){return "text/html";}
      if(FilenameExtension.equals("TXT")||FilenameExtension.equals("txt")){return "text/plain";}
      if(FilenameExtension.equals("VSD")||FilenameExtension.equals("vsd")){return "application/vnd.visio";}
      if(FilenameExtension.equals("PPTX")||FilenameExtension.equals("pptx")||
         FilenameExtension.equals("PPT")||FilenameExtension.equals("ppt")){return "application/vnd.ms-powerpoint";}
      if(FilenameExtension.equals("DOCX")||FilenameExtension.equals("docx")||
         FilenameExtension.equals("DOC")||FilenameExtension.equals("doc")){return "application/msword";}
      if(FilenameExtension.equals("XML")||FilenameExtension.equals("xml")){return "text/xml";}
      if(FilenameExtension.equals("MP4")||FilenameExtension.equals("mp4")){
         return "video/mp4";
      }
      return "text/html";
    }

   /**
    * 上传视频
    * @param file 视频文件
    * @return
    * @throws IOException
    */
   public static String uploadvideo(MultipartFile file) throws IOException {
      StringBuffer fileName = new StringBuffer();
      String fileExtension  = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
      InputStream inputStream =new ByteArrayInputStream(file.getBytes());
      //首页视频
      fileName.append(OssEnum.test.getName());
      fileName.append( UUID.randomUUID().toString()+fileExtension);

      OSSClient ossClient=new OSSClient(ossConfig.getEndpoint(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
      //创建上传Object的Metadata
      ObjectMetadata objectMetadata=new ObjectMetadata();
      objectMetadata.setContentLength(inputStream.available());
      objectMetadata.setContentEncoding("utf-8");
      objectMetadata.setCacheControl("no-cache");
      objectMetadata.setHeader("Pragma", "no-cache");
      objectMetadata.setContentType(contentType(fileName.substring(fileName.lastIndexOf(".")+1)));
      objectMetadata.setContentDisposition("inline;filename=" + fileName);
      //上传文件
      ossClient.putObject(ossConfig.getBucketNameVideo(), fileName.toString(), inputStream, objectMetadata);
      return ossConfig.getAccessUrlVideo()+"/" +fileName;
   }

   /**
    * 视频内容安全审核--任务发送
    * @param url 视频的url地址
    * @return
    * @throws ClientException
    * @throws UnsupportedEncodingException
    */
   public static String videoContentSecurity(String url) throws ClientException, UnsupportedEncodingException {
      //请替换成你自己的accessKeyId、accessKeySecret
      IClientProfile profile = DefaultProfile.getProfile(ossConfig.getRegionId(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
      DefaultProfile.addEndpoint(ossConfig.getEndPointName(), ossConfig.getRegionId(), "Green", ossConfig.getDomain());
      IAcsClient client = new DefaultAcsClient(profile);

      VideoAsyncScanRequest videoAsyncScanRequest = new VideoAsyncScanRequest();
      videoAsyncScanRequest.setAcceptFormat(FormatType.JSON); // 指定api返回格式
      videoAsyncScanRequest.setMethod(com.aliyuncs.http.MethodType.POST); // 指定请求方法

      List<Map<String, Object>> tasks = new ArrayList<Map<String, Object>>();
      Map<String, Object> task = new LinkedHashMap<String, Object>();
      task.put("dataId", UUID.randomUUID().toString());
      task.put("url", url);

      tasks.add(task);
      /**
       * 设置要检测的场景, 计费是按照该处传递的场景进行
       * 视频默认1秒截取一帧,您可以自行控制截帧频率,收费按照视频的截帧数量以及每一帧的检测场景进行计费
       * 举例:1分钟的视频截帧60张,检测色情和暴恐涉政2个场景,收费按照60张暴恐+60张暴恐涉政进行计费
       * porn: porn表示色情场景检测,terrorism表示暴恐涉政场景检测
       */
      JSONObject data = new JSONObject();
      data.put("scenes", Arrays.asList("porn", "terrorism"));
      data.put("tasks", tasks);

      videoAsyncScanRequest.setHttpContent(data.toJSONString().getBytes("UTF-8"), "UTF-8", FormatType.JSON);

      /**
       * 请务必设置超时时间
       */
      videoAsyncScanRequest.setConnectTimeout(3000);
      videoAsyncScanRequest.setReadTimeout(6000);
      try {
         HttpResponse httpResponse = client.doAction(videoAsyncScanRequest);

         if(httpResponse.isSuccess()){
            JSONObject jsonObject = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
            System.out.println(JSON.toJSONString(jsonObject, true));
            if (200 == jsonObject.getInteger("code")) {
               JSONArray taskResults = jsonObject.getJSONArray("data");
               for (Object taskResult : taskResults) {
                  if(200 == ((JSONObject)taskResult).getInteger("code")){
                     String taskId = ((JSONObject) taskResult).getString("taskId");
                      return taskId;
                  }else{
                     log.error("task process fail:" + ((JSONObject)taskResult).getInteger("code"));
                  }
               }
            } else {
               log.error("detect not success. code:" + jsonObject.getInteger("code"));
            }
         }else{
            System.out.println("response not success. status:" + httpResponse.getStatus());
         }
      } catch (ServerException e) {
         e.printStackTrace();
      } catch (ClientException e) {
         e.printStackTrace();
      }
      return null;
   }

   /**
    * 视频内容安全审核--异步结果解析
    * @param taskId 解析任务id
    * @return
    * @throws ClientException
    * @throws UnsupportedEncodingException
    */
   public static Boolean videoParseResult(String taskId) throws ClientException, UnsupportedEncodingException {
      IClientProfile profile = DefaultProfile.getProfile(ossConfig.getRegionId(), ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret());
      DefaultProfile.addEndpoint(ossConfig.getEndPointName(), ossConfig.getRegionId(), "Green", ossConfig.getDomain());
      IAcsClient client = new DefaultAcsClient(profile);

      VideoAsyncScanResultsRequest videoAsyncScanResultsRequest = new VideoAsyncScanResultsRequest();
      videoAsyncScanResultsRequest.setAcceptFormat(FormatType.JSON);

      List<String> taskList = new ArrayList<String>();
      // 这里添加要查询的taskId,提交任务的时候需要自行保存taskId
      taskList.add(taskId);

      videoAsyncScanResultsRequest.setHttpContent(JSON.toJSONString(taskList).getBytes("UTF-8"), "UTF-8", FormatType.JSON);

      /**
       * 请务必设置超时时间
       */
      videoAsyncScanResultsRequest.setConnectTimeout(3000);
      videoAsyncScanResultsRequest.setReadTimeout(6000);
      try {
         HttpResponse httpResponse = client.doAction(videoAsyncScanResultsRequest);
         if(httpResponse.isSuccess()){
            JSONObject jsonObject = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
            log.info("视频内容解析结果-->{}",jsonObject);
            if (200 == jsonObject.getInteger("code")) {
               JSONArray taskResults = jsonObject.getJSONArray("data");
               for (Object taskResult : taskResults) {
                  if(200 == ((JSONObject)taskResult).getInteger("code")){
                     JSONArray sceneResults = ((JSONObject)taskResult).getJSONArray("results");
                     Boolean result = true;
                     for (Object sceneResult : sceneResults) {
                        //对每一个常见进行解析
                        Boolean checkResult = parseResult(sceneResult);
                        result = result&&checkResult;
                     }
                     return result;
                  }else{
                     log.error("task process fail:" + ((JSONObject)taskResult).getInteger("code"));
                     return false;
                  }
               }
            } else {
               log.error("detect not success. code:" + jsonObject.getInteger("code"));
                    return false;
            }
         }else{
            log.error("response not success. status:" + httpResponse.getStatus());
                return false;
         }
      } catch (ServerException e) {
         e.printStackTrace();
      } catch (ClientException e) {
         e.printStackTrace();
      }
      return false;
   }

   /**
    * 返回内容解析
    * @param sceneResult 解析对象
    * @return
    */
   private static Boolean parseResult(Object sceneResult){
      try {
         String scene = ((JSONObject)sceneResult).getString("scene");
         String suggestion = ((JSONObject)sceneResult).getString("suggestion");
         Double rate = ((JSONObject)sceneResult).getDouble("rate");
         /**
          * porn: 反色情
          * terrorism: 反暴恐
          * qrcode: 二维码
          * ad: 图片广告
          * ocr: 文字识别
          */
         if ("porn".equals(scene)) {
            //反色情,true表示合格
            return "pass".equals(suggestion) && rate >= 99;
         }
         if("terrorism".equals(scene)){
            //反暴恐,true表示合格
            return  "pass".equals(suggestion) && rate >= 99;
         }
         return false;
      }catch (Exception e){
         log.error("图片内容安全审核,返回解析信息错误");
         e.printStackTrace();
         return false;
      }
   }

   /**
    * 视频内容安全审核,通过视频截帧
    * @param image
    * @param duration
    * @return
    */
   public static Boolean videoContentSecurityByDuration(String image, Integer duration) throws UnsupportedEncodingException, ClientException {
      for(int i=1;i<=duration;i++){
         /**
          * 视频截至图片的url
          * t   截图时间  单位ms,[0,视频时长] 如t_1000, 表示: 视频第一秒
          * w   截图宽度,如果指定为0则自动计算   像素值:[0,视频宽度], 如:w_0
          * h   截图高度,如果指定为0则自动计算,如果w和h都为0则输出为原视频宽高 像素值:[0,视频高度],如:h_0
          * m   截图模式,不指定则为默认模式,根据时间精确截图,如果指定为fast则截取该时间点之前的最近的一个关键帧    枚举值:fast,如m_fast
          * f   输出图片格式  枚举值:jpg、png
          */
         Boolean result = contentSecurity(image+"?x-oss-process=video/snapshot,t_"+i*1000+",f_jpg,w_0,h_0,f_jpg,m_fast",99);
         if(!result){
            //result=false,表示违法视频
            return false;
         }
      }
      return true;
   }
}

文明上网,理性发言
客户端 Android iPhone WP7