为什么带有 get .mp4 文件的 Apache tika 响应内容类型为“video/quicktime”?

问题描述 投票:0回答:4

我使用此函数获取文件 contentType ,当使用 .jpg 文件时接收“image/jpg”。使用 .mp4 接收“video/quicktime”

public static String detectMediaType(String fileName,byte[] data) {
    ByteArrayInputStream inputStream = new ByteArrayInputStream(data);
    AutoDetectParser parser = new AutoDetectParser();
    Detector detector = parser.getDetector();
    Metadata md = new Metadata();
    md.add(Metadata.RESOURCE_NAME_KEY, fileName);
    try{
        MediaType mediaType = detector.detect(inputStream, md);
        return mediaType.toString();
    }catch (IOException ex){
        throw new RuntimeException("Failed to detect mediaType for file: " + fileName,ex);
    }
}
java image mp4 apache-tika
4个回答
1
投票

我遇到了同样的问题,并且想知道为什么在使用上面的答案后我仍然得到“video/quicktime”作为 Mimetype。总结一下一切:

  • 使用解析器来检测元数据(如第一个答案)

  • 使用TikaInputStream(如第二个答案中所示),但不要尝试重用它

  • 在依赖项中包含适合您的情况的特定解析器(在本例中是 org.apache.tika.parser.mp4.MP4Parser

     Tika tika = new Tika();
     String detectedType;
    
     try (
       TikaInputStream parserInputStream = TikaInputStream.get(new ByteArrayInputStream(bytes));
       TikaInputStream detectionInputStream = TikaInputStream.get(new ByteArrayInputStream(bytes));
     ) {
       // reading metadata from file, important for video type detection (quicktime, mp4, ...)
       Parser parser = new AutoDetectParser();
       BodyContentHandler handler = new BodyContentHandler();
       Metadata metadata = new Metadata();
       ParseContext context = new ParseContext();
       parser.parse(parserInputStream, handler, metadata, context);
       // read the type
       // would like to reuse the stream from above (used by parser), but this can end in a wrong mimetype
       // parserInputStream.reset();
       detectedType = tika.detect(detectionInputStream, metadata);
     } catch (Exception ex) {
       detectedType = tika.detect(bytes);
       log.warn("Could not read MimeType of file '{}' using Metadata, using fallback detection: '{}'", file.getOriginalFilename(), detectedType);
     }
    

依赖关系,例如在 Maven 中:

<dependency>
  <groupId>org.apache.tika</groupId>
  <artifactId>tika-core</artifactId>
</dependency>
<dependency>
  <groupId>org.apache.tika</groupId>
  <artifactId>tika-parser-audiovideo-module</artifactId>
  <scope>runtime</scope>
</dependency>

0
投票

这是预期的,因为您正在使用 tika 检测器功能,该功能对于 mp4 或其他 QuickTime 格式返回通用“视频/quicktime”。如果您需要获得像“video/mp4”这样的精确类型,您应该另外使用 tika 解析器,例如:

if (mediaType.equals(MediaType.video("quicktime"))) {
    Parser parser = new AutoDetectParser();
    ContentHandler handler = new BodyContentHandler();
    Metadata metadata = new Metadata();
    ParseContext context = new ParseContext();
    parser.parse(inputStream, handler, metadata, context);
}

0
投票

我在使用 Tikas DefaultDetector 时遇到了同样的问题。

解决方案,如下所示:https://tika.apache.org/2.3.0/detection.html(在“容器感知检测”下),是使用

TikaInputStream
,而不是标准
InputStream
.

detector.detect(TikaInputStream.get(inputStream), metadata);
  • 不要忘记关闭流。
  • 还要确保
    tika-parsers-*
    jar 位于类路径中。

0
投票

在这里对其他答案添加一些澄清。

@uhon答案仅在使用

TikaInputStream.get
File
调用静态
Path
方法时才会产生影响,以便Tika可以根据文件名添加一些元数据。当 Tika 看到
.mp4
扩展名时,它将通过将
MP4Parser
应用于问题来触发 Tika 的容器感知检测。

如果输入是

byte[]
,则只需将其包装在
TikaInputStream
中而不在
MetaData
参数中提供文件名将不会有任何区别,因为
TikaInputStream
没有额外的元数据可提供。

@Dasch33答案基本上是正确的,除了如果你已经知道你将使用重量级解析器而不仅仅是检测器,

TikaInputStream
对于这个用例没有任何区别。请注意,额外的元数据可能会对其他容器类型(例如 zip 和 OLE2)产生影响,但在我的测试中它不会影响 MP4 视频的解析 -- Tika 的解析器足够聪明,可以在没有它的情况下委托给它的
MP4Parser
。将任何内容(包括
ByteArrayInputStream
)传递给解析器将正确检测
video/mp4

@zygimantus 的答案最接近目标,首先使用轻量级检测器,然后有条件地应用较重的解析来缩小视频类型的范围。然而,没有必要创建所有这些对象,并且它没有进行适当的资源管理。解决方案可以很简单:

// if your input is an InputStream or File or Path // it can be passed directly to `tika.parse`. byte[] input = ... var metaData = new MetaData() try(var ignored = tika.parse(new ByteArrayInputStream(input), metaData)) { } catch (IOException e) { ... } var mime = metaData.get(Metadata.CONTENT_TYPE);

tika.parse

 的调用会返回 
Reader
,提供对输入文本内容的访问。在这里,对于这个用例,我们不关心文本内容——我们只需要解析器提供的高级检测功能。但尽管如此,
返回的 reader 负责关闭流资源,因此我们需要将其封装在 try-with-resources 中。

© www.soinside.com 2019 - 2024. All rights reserved.