/*********************************************************************************************************** * * Factory method extracting data from a {@link Metadata} instance. * * @param metadata the data source * @return the {@code ITunesComment} * **********************************************************************************************************/ @Nonnull public static Optional<ITunesComment> from (final @Nonnull Metadata metadata) { return metadata.get(ENCODER).flatMap( encoders -> encoders.stream().anyMatch(encoder -> encoder.startsWith("iTunes")) ? metadata.get(COMMENT).flatMap(comments -> from(comments)) : Optional.empty()); }
/******************************************************************************************************************* * * Exports the cover art of a record. * * @param id the record id * @return the cover art image * ******************************************************************************************************************/ @RequestMapping(value = "/record/{id}/coverart") public ResponseEntity<byte[]> getRecordCoverArt (final @PathVariable String id) { log.info("getRecordCoverArt({})", id); checkStatus(); return catalog.findTracks().inRecord(new Id(id)) .stream() .flatMap(track -> track.asMany(AudioFileSupplier).stream()) .map(afs -> afs.getAudioFile()) .flatMap(af -> af.getMetadata().getAll(ARTWORK).stream()) .findAny() .map(bytes -> bytesResponse(bytes, "image", "jpeg", "coverart.jpg")) .orElseThrow(NotFoundException::new); }
metadata = metadata.with(FILE_SIZE, Files.size(normalizedPath)) .with(DURATION, Duration.ofSeconds(header.getTrackLength())) .with(BIT_RATE, (int)header.getBitRateAsNumber()) .with(SAMPLE_RATE, header.getSampleRateAsNumber()) .with(BITS_PER_SAMPLE, header.getBitsPerSample()) .with(CHANNELS, parseOptionalInt(header.getChannels())) .with(FORMAT, Optional.ofNullable(header.getFormat())) .with(ENCODING_TYPE, Optional.ofNullable(header.getEncodingType())) .with(ARTIST, tag.getFirst(FieldKey.ARTIST)) .with(ALBUM, tag.getFirst(FieldKey.ALBUM)) .with(TITLE, tag.getFirst(FieldKey.TITLE)) .with(COMMENT, tag.getAll(FieldKey.COMMENT)) .with(TRACK_NUMBER, parseOptionalInt(tag.getFirst(FieldKey.TRACK))) .with(DISK_NUMBER, parseOptionalInt(tag.getFirst(FieldKey.DISC_NO))) .with(DISK_COUNT, parseOptionalInt(tag.getFirst(FieldKey.DISC_TOTAL))) .with(COMPOSER, tag.getFirst(FieldKey.COMPOSER)) .with(MBZ_TRACK_ID, id(tag.getFirst(FieldKey.MUSICBRAINZ_TRACK_ID))) .with(MBZ_WORK_ID, id(tag.getFirst(FieldKey.MUSICBRAINZ_WORK_ID))) .with(MBZ_DISC_ID, id(tag.getFirst(FieldKey.MUSICBRAINZ_DISC_ID))) .with(MBZ_ARTIST_ID, optionalList(tag.getAll(FieldKey.MUSICBRAINZ_ARTISTID).stream() .filter(s -> ((s != null) && !"".equals(s))) .flatMap(s -> Stream.of(s.split("/"))) // FIXME:correct? metadata = metadata.with(key, values); metadata = metadata.with(ITUNES_COMMENT, ITunesComment.from(metadata));
final String releaseId = rmd.getRelease().getId(); final List<DefTrackData> tracks = medium.getTrackList().getDefTrack(); final String embeddedRecordTitle = metadata.get(ALBUM).get(); // .orElse(parent.getPath().toFile().getName()); final Cddb cddb = metadata.get(CDDB).get(); final String recordTitle = rmd.pickTitle(); final IRI embeddedRecordIri = recordIriOf(metadata, embeddedRecordTitle);
+ metadata.get(DISK_COUNT).map(dc -> (dc.intValue() == 1) ? "" : metadata.get(DISK_NUMBER).map(n -> " _#" + n).orElse("")).orElse("") + ".n3"); final Path actualResult = TEST_RESULTS.resolve("musicbrainz").resolve(testSetName).resolve(relativePath); final Model model = optionalModel.get(); final boolean matched = !model.isEmpty(); final boolean hasCddb = metadata.get(CDDB).isPresent(); unmatched.add(recordName + " / " + metadata.get(CDDB).get().getToc());
final Cddb requestedCddb = metadata.get(ITUNES_COMMENT).get().getCddb(); final Optional<String> dTitle = album.getProperty("DTITLE");
final Metadata trackMetadata = datum.getMetadata(); item.addResource(audioResourceOf(audioFile)); trackMetadata.get(TRACK_NUMBER).ifPresent(item::setOriginalTrackNumber);
/******************************************************************************************************************* * * Test sets iTunes-fg-20160504-1 and iTunes-fg-20161210-1 manually validated on 2017-01-07 18:00. * ******************************************************************************************************************/ @Test(dataProvider = "trackResourcesProvider") public void must_correctly_download_CDDB_resources (final @Nonnull TestSetTriple triple) throws Exception { // given final Path relativePath = triple.getRelativePath(); final String testSetName = triple.getTestSetName(); final Path actualResult = TEST_RESULTS.resolve("cddb").resolve(testSetName).resolve(relativePath); final Path expectedResult = EXPECTED_RESULTS.resolve("cddb").resolve(testSetName).resolve(relativePath); underTest.setCachePath(CDDB_CACHE.resolve(testSetName)); final Metadata metadata = mockMetadataFrom(triple.getFilePath()); final Optional<Cddb> cddb = metadata.get(CDDB); // when final RestResponse<CddbAlbum> response = underTest.findCddbAlbum(metadata); // then final String string = response.map(CddbAlbum::toDumpString).orElse(cddb.isPresent() ? "NOT FOUND" : "NO ITUNES COMMENT"); log.info(">>>> writing to {}", actualResult); Files.createDirectories(actualResult.getParent()); Files.write(actualResult, singletonList(string), UTF_8); assertSameContents(expectedResult, actualResult); } }
/******************************************************************************************************************* * * @param id the audio file id * @return the binary contents * ******************************************************************************************************************/ @RequestMapping(value = "/audiofile/{id}/coverart") public ResponseEntity<byte[]> getAudioFileCoverArt (final @PathVariable String id) { log.info("getAudioFileCoverArt({})", id); checkStatus(); final Optional<AudioFile> audioFile = catalog.findAudioFiles().withId(new Id(id)).optionalResult(); log.debug(">>>> audioFile: {}", audioFile); return audioFile.flatMap(file -> file.getMetadata().getAll(ARTWORK).stream().findFirst()) .map(bytes -> bytesResponse(bytes, "image", "jpeg", "coverart.jpg")) .orElseThrow(NotFoundException::new); }
@Nonnull private Res audioResourceOf (final @Nonnull AudioFile audioFile) { final ProtocolInfo protocolInfo = new DLNAProtocolInfo(Protocol.HTTP_GET, "*", "audio/mpeg", "*"); // FIXME: MIME final Metadata audioFileMetadata = audioFile.getMetadata(); final Res resource = new Res(protocolInfo, audioFileMetadata.get(FILE_SIZE).orElse(null), server.absoluteUrl(String.format("rest/audiofile/%s/content", audioFile.getId().stringValue()))); audioFileMetadata.get(DURATION).ifPresent(duration -> resource.setDuration(durationToString(duration))); audioFileMetadata.get(BIT_RATE).ifPresent(bitRate -> resource.setBitrate((long)(int)bitRate)); audioFileMetadata.get(BITS_PER_SAMPLE).ifPresent(bitPerSample -> resource.setBitsPerSample((long)(int)bitPerSample)); audioFileMetadata.get(CHANNELS).ifPresent(channels -> resource.setNrAudioChannels((long)(int)channels)); audioFileMetadata.get(SAMPLE_RATE).ifPresent(sampleRate -> resource.setSampleFrequency((long)(int)sampleRate)); return resource; }
public RepositoryTrack (final @Nonnull Repository repository, final @Nonnull BindingSet bindingSet) { super(repository, bindingSet, "track"); audioFilePath = toPath(bindingSet.getBinding("path")); duration = toDuration(bindingSet.getBinding("duration")); trackNumber = toInteger(bindingSet.getBinding("track_number")); diskNumber = toInteger(bindingSet.getBinding("disk_number")); diskCount = toInteger(bindingSet.getBinding("disk_count")); // this.recordRdfsLabel = toString(bindingSet.getBinding("record_label")); metadata = new MetadataSupport(audioFilePath).with(DURATION, duration) .with(TRACK_NUMBER, trackNumber) .with(DISK_NUMBER, diskNumber) .with(DISK_COUNT, diskCount); audioFile = new Memoize<>(() -> new RepositoryAudioFile(repository, bindingSet)); }
public AudioFileResource (final @Nonnull AudioFile audioFile) { this.id = audioFile.getId().stringValue(); this.displayName = audioFile.as(Displayable).getDisplayName(); this.path = audioFile.getPath().toString(); final Metadata metadata = audioFile.getMetadata(); this.fileSize = metadata.get(FILE_SIZE); this.duration = metadata.get(DURATION).map(Duration::toString); final String myUri = resourceUri("audiofile", id); this.content = myUri + "/content"; this.coverArt = metadata.get(ARTWORK).map(x -> myUri + "/coverart"); } }
@Override @Nonnull protected List<? extends MusicArtist> computeNeededResults() { return metadata.get(metadataKey).map(artistName -> asList(new ArtistFallback(artistName))).orElse(emptyList()); }
/******************************************************************************************************************* * * {@inheritDoc} * ******************************************************************************************************************/ @Override @Nonnull public <T> T getAll (final @Nonnull Key<T> key) { final T list = (T)properties.get(key); return (list != null) ? list : fallback.flatMap(fb -> fb.apply(key).get(key)).orElse((T)Collections.emptyList()); }
/******************************************************************************************************************* * * {@inheritDoc} * ******************************************************************************************************************/ @Override @Nonnull public <T> Optional<T> get (final @Nonnull Key<T> key) { return properties.containsKey(key) ? Optional.ofNullable((T)properties.get(key)) : fallback.flatMap(fb -> fb.apply(key).get(key)); }
public RepositoryAudioFile (final @Nonnull Repository repository, final @Nonnull BindingSet bindingSet) { super(repository, bindingSet, "audioFile", rdfsLabelOf(bindingSet.getBinding("path").getValue().stringValue())); this.path = toPath(bindingSet.getBinding("path")); this.duration = toDuration(bindingSet.getBinding("duration")); this.fileSize = toLong(bindingSet.getBinding("fileSize")); this.trackId = toId(bindingSet.getBinding("track")); this.metadata = new MetadataSupport(path).with(TITLE, rdfsLabel) .with(DURATION, duration) .with(FILE_SIZE, fileSize) .withFallback(key -> fallbackMetadata.get(this::loadFallbackMetadata)); }
/******************************************************************************************************************* * * {@inheritDoc} * ******************************************************************************************************************/ @Override @Nonnull public RestResponse<CddbAlbum> findCddbAlbum (final @Nonnull Metadata metadata) throws IOException, InterruptedException { return metadata.get(CDDB).map(_f(this::findCddbAlbum)).orElse(CddbResponse.empty()); }
@Override @Nonnull public String getDisplayName() { return file.getMetadata().get(TITLE).orElse("???"); } }