/** * A stateless method that determines if 2 or more Composition documents corresponding to the same * title can be inferred to represent the same presentation timeline. This method is present to * work around current limitations in the IMF eco system wherein CPL's might not be built * incrementally to include all the IMF essences that are a part of the same timeline * * @param referenceCPLPayloadRecord - a payload record corresponding to a Reference Composition * document, perhaps the first composition playlist document that was delivered for a * particular composition. * @param cplPayloads - a list of payload records corresponding to each of the Composition * documents that need to be verified for mergeability * @return a boolean indicating if the CPLs can be merged or not * @throws IOException - any I/O related error is exposed through an IOException */ public static List<ErrorLogger.ErrorObject> isCPLMergeable( PayloadRecord referenceCPLPayloadRecord, List<PayloadRecord> cplPayloads) throws IOException { IMFErrorLogger imfErrorLogger = new IMFErrorLoggerImpl(); List<PayloadRecord> cplPayloadRecords = Collections.unmodifiableList(cplPayloads); List<Composition> compositions = new ArrayList<>(); try { compositions.add( new Composition(new ByteArrayByteRangeProvider(referenceCPLPayloadRecord.getPayload()))); } catch (IMFException e) { imfErrorLogger.addAllErrors(e.getErrors()); } for (PayloadRecord cpl : cplPayloadRecords) { try { compositions.add(new Composition(new ByteArrayByteRangeProvider(cpl.getPayload()))); } catch (IMFException e) { imfErrorLogger.addAllErrors(e.getErrors()); } } if (imfErrorLogger.hasFatalErrors()) { return imfErrorLogger.getErrors(); } VirtualTrack referenceVideoVirtualTrack = compositions.get(0).getVideoVirtualTrack(); UUID referenceCPLUUID = compositions.get(0).getUUID(); for (int i = 1; i < compositions.size(); i++) { if (!referenceVideoVirtualTrack.equivalent(compositions.get(i).getVideoVirtualTrack())) { imfErrorLogger.addError( IMFErrorLogger.IMFErrors.ErrorCodes.IMF_CPL_ERROR, IMFErrorLogger.IMFErrors.ErrorLevels.WARNING, String.format( "CPL Id %s can't be merged with Reference CPL Id %s, since the video virtual tracks do not seem to represent the same timeline.", compositions.get(i).getUUID(), referenceCPLUUID)); } } /** * Perform AudioTrack mergeability checks 1) Identify AudioTracks that are the same language 2) * Compare language tracks to see if they represent the same timeline */ Boolean bAudioVirtualTrackMapFail = false; List<Map<Set<DOMNodeObjectModel>, ? extends VirtualTrack>> audioVirtualTracksMapList = new ArrayList<>(); for (Composition composition : compositions) { try { audioVirtualTracksMapList.add(composition.getAudioVirtualTracksMap()); } catch (IMFException e) { bAudioVirtualTrackMapFail = false; imfErrorLogger.addAllErrors(e.getErrors()); } } if (!bAudioVirtualTrackMapFail) { Map<Set<DOMNodeObjectModel>, ? extends VirtualTrack> referenceAudioVirtualTracksMap = audioVirtualTracksMapList.get(0); for (int i = 1; i < audioVirtualTracksMapList.size(); i++) { if (!compareAudioVirtualTrackMaps( Collections.unmodifiableMap(referenceAudioVirtualTracksMap), Collections.unmodifiableMap(audioVirtualTracksMapList.get(i)), imfErrorLogger)) { imfErrorLogger.addError( IMFErrorLogger.IMFErrors.ErrorCodes.IMF_CPL_ERROR, IMFErrorLogger.IMFErrors.ErrorLevels.WARNING, String.format( "CPL Id %s can't be merged with Reference CPL Id %s, since 2 same language audio tracks do not seem to represent the same timeline.", compositions.get(i).getUUID(), referenceCPLUUID)); } } } /** Perform MarkerTrack mergeability checks */ Composition.VirtualTrack referenceMarkerVirtualTrack = compositions.get(0).getMarkerVirtualTrack(); if (referenceMarkerVirtualTrack != null) { UUID referenceMarkerCPLUUID = compositions.get(0).getUUID(); for (int i = 1; i < compositions.size(); i++) { if (!referenceVideoVirtualTrack.equivalent(compositions.get(i).getMarkerVirtualTrack())) { imfErrorLogger.addError( IMFErrorLogger.IMFErrors.ErrorCodes.IMF_CPL_ERROR, IMFErrorLogger.IMFErrors.ErrorLevels.WARNING, String.format( "CPL Id %s can't be merged with Reference CPL Id %s, since the marker virtual tracks do not seem to represent the same timeline.", compositions.get(i).getUUID(), referenceMarkerCPLUUID)); } } } return imfErrorLogger.getErrors(); }