diff --git a/main/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaContainerProbe.java b/main/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaContainerProbe.java index 31a20ffa..0171d64a 100644 --- a/main/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaContainerProbe.java +++ b/main/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaContainerProbe.java @@ -59,7 +59,13 @@ public MediaContainerDetectionResult probe(AudioReference reference, SeekableInp return unsupportedFormat(this, "No supported audio tracks present in the file."); } - return supportedFormat(this, null, new AudioTrackInfo(UNKNOWN_TITLE, UNKNOWN_ARTIST, + String title = file.getTitle(); + String actualTitle = title == null || title.isEmpty() ? UNKNOWN_TITLE : title; + + String artist = file.getArtist(); + String actualArtist = artist == null || artist.isEmpty() ? UNKNOWN_ARTIST : artist; + + return supportedFormat(this, null, new AudioTrackInfo(actualTitle, actualArtist, (long) file.getDuration(), reference.identifier, false, reference.identifier)); } diff --git a/main/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaStreamingFile.java b/main/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaStreamingFile.java index 59ac4c84..3506f73a 100644 --- a/main/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaStreamingFile.java +++ b/main/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/MatroskaStreamingFile.java @@ -16,6 +16,9 @@ public class MatroskaStreamingFile { private final MatroskaFileReader reader; + private String title; + private String artist; + private long timecodeScale = 1000000; private double duration; private final ArrayList trackList = new ArrayList<>(); @@ -42,6 +45,17 @@ public long getTimecodeScale() { return timecodeScale; } + /** + * @return The title for this file. + */ + public String getTitle() { + return title; + } + + public String getArtist() { + return artist; + } + /** * @return Total duration of the file */ @@ -114,6 +128,8 @@ private void parseSegmentElement(MatroskaElement segmentElement) throws IOExcept while ((child = reader.readNextElement(segmentElement)) != null) { if (child.is(MatroskaElementType.Info)) { parseSegmentInfo(child); + } else if (child.is(MatroskaElementType.Tags)) { + parseTags(child); } else if (child.is(MatroskaElementType.Tracks)) { parseTracks(child); } else if (child.is(MatroskaElementType.Cluster)) { @@ -378,6 +394,8 @@ private void parseSegmentInfo(MatroskaElement infoElement) throws IOException { duration = reader.asDouble(child); } else if (child.is(MatroskaElementType.TimecodeScale)) { timecodeScale = reader.asLong(child); + } else if (child.is(MatroskaElementType.Title)) { + title = reader.asString(child); } reader.skip(child); @@ -395,4 +413,43 @@ private void parseTracks(MatroskaElement tracksElement) throws IOException { reader.skip(child); } } + + private void parseTags(MatroskaElement tagsElement) throws IOException { + MatroskaElement child; + + while ((child = reader.readNextElement(tagsElement)) != null) { + if (child.is(MatroskaElementType.Tag)) { + parseTag(child); + } + + reader.skip(child); + } + } + + private void parseTag(MatroskaElement tagElement) throws IOException { + MatroskaElement child; + + while ((child = reader.readNextElement(tagElement)) != null) { + if (child.is(MatroskaElementType.SimpleTag)) { + parseSimpleTag(child); + } + + reader.skip(child); + } + } + + private void parseSimpleTag(MatroskaElement simpleTagElement) throws IOException { + MatroskaElement child; + String tagName = null; + + while ((child = reader.readNextElement(simpleTagElement)) != null) { + if (child.is(MatroskaElementType.TagName)) { + tagName = reader.asString(child); + } else if (child.is(MatroskaElementType.TagString)) { + if ("artist".equalsIgnoreCase(tagName)) { + artist = reader.asString(child); + } + } + } + } } diff --git a/main/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaElementType.java b/main/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaElementType.java index 49c3705a..ccb23fe8 100644 --- a/main/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaElementType.java +++ b/main/src/main/java/com/sedmelluq/discord/lavaplayer/container/matroska/format/MatroskaElementType.java @@ -17,6 +17,9 @@ public enum MatroskaElementType { SeekId(DataType.BINARY, new int[]{0x53, 0xAB}), SeekPosition(DataType.UNSIGNED_INTEGER, new int[]{0x53, 0xAC}), Info(DataType.MASTER, new int[]{0x15, 0x49, 0xA9, 0x66}), + Tags(DataType.MASTER, new int[] { 0x12, 0x54, 0xC3, 0x67 }), + Tag(DataType.MASTER, new int[] { 0x73, 0x73 }), + SimpleTag(DataType.MASTER, new int[] { 0x67, 0xC8 }), Duration(DataType.FLOAT, new int[]{0x44, 0x89}), TimecodeScale(DataType.UNSIGNED_INTEGER, new int[]{0x2A, 0xD7, 0xB1}), Cluster(DataType.MASTER, new int[]{0x1F, 0x43, 0xB6, 0x75}), @@ -45,9 +48,12 @@ public enum MatroskaElementType { CueTrackPositions(DataType.MASTER, new int[]{0xB7}), CueTrack(DataType.UNSIGNED_INTEGER, new int[]{0xF7}), CueClusterPosition(DataType.UNSIGNED_INTEGER, new int[]{0xF1}), + Title(DataType.STRING, new int[] { 0x7B, 0xA9 }), + TagName(DataType.STRING, new int[] { 0x45, 0xA3 }), + TagString(DataType.STRING, new int[] { 0x44, 0x87 }), Unknown(DataType.BINARY, new int[]{}); - private static Map mapping; + private static final Map mapping; /** * The ID as EBML code bytes.