private List<BroadcastMetadata> getBroadcastMetadata( List<String> fileObjectPids, InfrastructureContext context, TranscodeRequest request) throws ProcessorException { Map<String, BroadcastMetadata> pidMap = new HashMap<String, BroadcastMetadata>(); CentralWebservice doms = CentralWebserviceFactory.getServiceInstance(context); List<BroadcastMetadata> broadcastMetadataList = new ArrayList<BroadcastMetadata>(); for (String fileObjectPid : fileObjectPids) { BroadcastMetadata broadcastMetadata = null; try { String broadcastMetadataXml = doms.getDatastreamContents(fileObjectPid, "BROADCAST_METADATA"); logger.debug("Found file metadata '" + fileObjectPid + "' :\n" + broadcastMetadataXml); broadcastMetadata = JAXBContext.newInstance(BroadcastMetadata.class) .createUnmarshaller() .unmarshal( new StreamSource(new StringReader(broadcastMetadataXml)), BroadcastMetadata.class) .getValue(); } catch (Exception e) { throw new ProcessorException( "Failed to get Broadcast Metadata for " + request.getObjectPid(), e); } broadcastMetadataList.add(broadcastMetadata); pidMap.put(fileObjectPid, broadcastMetadata); } request.setPidMap(pidMap); return broadcastMetadataList; }
/** * Returns either a list of all the files connected to this program or the single file that * represents this program exactly, if such a file exists. * * @param request * @param context * @return * @throws InvalidCredentialsException * @throws InvalidResourceException * @throws MethodFailedException */ private List<String> findFileObjects(TranscodeRequest request, InfrastructureContext context) throws InvalidCredentialsException, InvalidResourceException, MethodFailedException { CentralWebservice doms = CentralWebserviceFactory.getServiceInstance(context); List<String> fileObjectPids = new ArrayList<String>(); List<Relation> relations = doms.getRelations(request.getObjectPid()); for (Relation relation : relations) { logger.debug( "Relation: " + request.getObjectPid() + " " + relation.getPredicate() + " " + relation.getObject()); if (relation.getPredicate().equals(HAS_EXACT_FILE_RELATION)) { fileObjectPids = new ArrayList<String>(); fileObjectPids.add(relation.getObject()); request.setHasExactFile(true); logger.debug( "Program " + request.getObjectPid() + " has an exact file " + relation.getObject()); return fileObjectPids; } else if (relation.getPredicate().equals(HAS_FILE_RELATION)) { fileObjectPids.add(relation.getObject()); } } return fileObjectPids; }
@Override protected void processThis(TranscodeRequest request, SingleTranscodingContext context) throws ProcessorException { List<String> fileObjectPids = null; try { fileObjectPids = findFileObjects(request, context); } catch (Exception e) { throw new ProcessorException("Failed to find file objects for " + request.getObjectPid(), e); } if (fileObjectPids.isEmpty()) { throw new ProcessorException( "No file-object relations for program " + request.getObjectPid()); } /* if (request.isHasExactFile()) { String uniqueFilePid = fileObjectPids.get(0); CentralWebservice doms = CentralWebserviceFactory.getServiceInstance(context); BroadcastMetadata broadcastMetadata = new BroadcastMetadata(); try { String filename = doms.getObjectProfile(uniqueFilePid).getTitle(); broadcastMetadata.setFilename(filename); } catch (Exception e) { throw new ProcessorException("" + e); } Map<String, BroadcastMetadata> pidMap = new HashMap<String, BroadcastMetadata>(); pidMap.put(uniqueFilePid, broadcastMetadata); request.setPidMap(pidMap); List<BroadcastMetadata> broadcastMetadatas = new ArrayList<BroadcastMetadata>(); broadcastMetadatas.add(broadcastMetadata); request.setBroadcastMetadata(broadcastMetadatas); } else {*/ // // // List<BroadcastMetadata> broadcastMetadata = getBroadcastMetadata(fileObjectPids, context, request); request.setBroadcastMetadata(broadcastMetadata); // } }
/** * For digitv broadcasts, detects and sets audio, video and dvbsub pids in the request. * * @param request * @param config * @throws ProcessorException */ @Override protected void processThis(TranscodeRequest request, ServletConfig config) throws ProcessorException { Long blocksize = 1880L; Long blockcount = clipSize / blocksize; String filename = null; Integer program; Long offset = null; if (request.getClips().size() == 1) { TranscodeRequest.FileClip clip = request.getClips().get(0); program = clip.getProgramId(); filename = clip.getFilepath(); offset = (new File(filename)).length() / 2L; } else { TranscodeRequest.FileClip clip = request.getClips().get(1); offset = 0L; program = clip.getProgramId(); filename = clip.getFilepath(); } String command = null; switch (request.getClipType()) { case MUX: command = "dd if=" + filename + " " + "bs=" + blocksize + " " + "count=" + blockcount + " " + "skip=" + offset / blocksize + " " + "|ffmpeg -i - "; break; case MPEG1: return; case MPEG2: return; case WAV: return; } extractPidsFromFfmpeg(request, command); if (request.getAudioPids().isEmpty() || request.getVideoPid() == null || request.getDvbsubPid() == null) { if (request.getClipType() == ClipTypeEnum.MUX) { command = "ffmpeg -i " + filename; extractPidsFromFfmpeg(request, command); } } if (request.getAudioPids().isEmpty() || request.getVideoPid() == null || request.getDvbsubPid() == null) { if (request.getClipType() == ClipTypeEnum.MUX) { command = " vlc -vv --no-audio --no-video --intf dummy --run-time 5 --play-and-exit " + filename; extractPidsFromVlc(request, command); } } }
private void extractPidsFromFfmpeg(TranscodeRequest request, String command) throws ProcessorException { log.info("Executing '" + command + "'"); ExternalJobRunner runner; try { runner = new ExternalJobRunner(new String[] {"bash", "-c", command}); log.debug("Command '" + command + "' returned with output '" + runner.getError()); } catch (IOException e) { throw new ProcessorException(e); } catch (InterruptedException e) { throw new ProcessorException(e); } catch (ExternalProcessTimedOutException e) { throw new ProcessorException(e); } Pattern thisProgramPattern = Pattern.compile(".*Program\\s" + request.getClips().get(0).getProgramId() + ".*"); Pattern programPattern = Pattern.compile(".*Program.*"); Pattern dvbsubPattern = Pattern.compile(".*Stream.*\\[(0x[0-9a-f]*)\\].*dvb.*sub.*"); Pattern videoPattern = Pattern.compile(".*Stream.*\\[(0x[0-9a-f]*)\\].*Video.*DAR\\s(([0-9]*):([0-9]*)).*"); Pattern audioPattern1 = Pattern.compile(".*Stream.*\\[(0x[0-9a-f]*)\\].*Audio.*"); Pattern audioPattern2 = Pattern.compile(".*Stream.*\\[(0x[0-9a-f]*)\\].*0x0011.*"); String[] commandOutput = runner.getError().split("\\n"); boolean foundProgram = false; for (String line : commandOutput) { log.debug("Checking line '" + line + "'"); if (foundProgram && programPattern.matcher(line).matches()) { log.debug("Found next program section, returning"); return; } if (thisProgramPattern.matcher(line).matches()) { log.debug("Found requested program"); foundProgram = true; } if (foundProgram) { Matcher dvbsubMatcher = dvbsubPattern.matcher(line); if (dvbsubMatcher.matches()) { request.setDvbsubPid(dvbsubMatcher.group(1)); log.info("Setting pid for dvbsub '" + dvbsubMatcher.group(1) + "'"); } Matcher videoMatcher = videoPattern.matcher(line); if (videoMatcher.matches()) { request.setVideoPid(videoMatcher.group(1)); log.info("Setting pid for video '" + videoMatcher.group(1) + "'"); if (line.contains("mpeg2video")) { request.setVideoFcc("mpgv"); } else if (line.contains("h264")) { request.setVideoFcc("h264"); } log.debug( "Identified video fourcc for " + request.getPid() + ": " + request.getVideoFcc()); request.setDisplayAspectRatioString(videoMatcher.group(2)); log.debug("Identified aspect ratio '" + request.getDisplayAspectRatioString() + "'"); } Matcher audioMatcher = audioPattern1.matcher(line); if (audioMatcher.matches()) { request.addAudioPid(audioMatcher.group(1)); log.info("Setting pid for audio '" + audioMatcher.group(1) + "'"); if (line.contains("aac_latm")) { request.setAudioFcc("mp4a"); } else if (line.contains("mp2")) { request.setAudioFcc("mpga"); } log.debug( "Identified audio fourcc for " + request.getPid() + ": " + request.getAudioFcc()); } audioMatcher = audioPattern2.matcher(line); if (audioMatcher.matches()) { request.addAudioPid(audioMatcher.group(1)); log.info("Setting pid for audio '" + audioMatcher.group(1) + "'"); request.setAudioFcc("mp4a"); log.debug( "Identified audio fourcc for " + request.getPid() + ": " + request.getAudioFcc()); } } } }
private void extractPidsFromVlc(TranscodeRequest request, String command) throws ProcessorException { log.info("Executing '" + command + "'"); ExternalJobRunner runner; try { runner = new ExternalJobRunner(new String[] {"bash", "-c", command}); log.debug("Command '" + command + "' returned with output '" + runner.getError()); } catch (IOException e) { throw new ProcessorException(e); } catch (InterruptedException e) { throw new ProcessorException(e); } catch (ExternalProcessTimedOutException e) { throw new ProcessorException(e); } Pattern thisProgramPattern = Pattern.compile(".*program number=" + request.getClips().get(0).getProgramId() + ".*"); Pattern programPattern = Pattern.compile(".*program number=.*"); Pattern dvbsubPattern = Pattern.compile(".*pid=([0-9]*).*fcc=dvbs.*"); Pattern videoPattern = Pattern.compile(".*pid=([0-9]*).*((fcc=mpgv)|(fcc=h264)).*"); Pattern audioPattern1 = Pattern.compile(".*pid=([0-9]*).*((fcc=mp4a)|(fcc=mpga)).*"); String[] commandOutput = runner.getError().split("\\n"); boolean foundProgram = false; for (String line : commandOutput) { log.debug("Checking line '" + line + "'"); if (foundProgram && programPattern.matcher(line).matches()) { log.debug("Found next program section, returning"); return; } if (thisProgramPattern.matcher(line).matches()) { log.debug("Found requested program"); foundProgram = true; } if (foundProgram) { Matcher dvbsubMatcher = dvbsubPattern.matcher(line); if (dvbsubMatcher.matches()) { request.setDvbsubPid(dvbsubMatcher.group(1)); log.info("Setting pid for dvbsub '" + dvbsubMatcher.group(1) + "'"); } Matcher videoMatcher = videoPattern.matcher(line); if (videoMatcher.matches()) { request.setVideoPid(videoMatcher.group(1)); log.info("Setting pid for video '" + videoMatcher.group(1) + "'"); if (line.contains("mpgv")) { request.setVideoFcc("mpgv"); } else if (line.contains("h264")) { request.setVideoFcc("h264"); } log.debug( "Identified video fourcc for " + request.getPid() + ": " + request.getVideoFcc()); } Matcher audioMatcher = audioPattern1.matcher(line); if (audioMatcher.matches()) { request.addAudioPid(audioMatcher.group(1)); log.info("Setting pid for audio '" + audioMatcher.group(1) + "'"); if (line.contains("mp4a")) { request.setAudioFcc("mp4a"); } else if (line.contains("mpga")) { request.setAudioFcc("mpga"); } log.debug( "Identified audio fourcc for " + request.getPid() + ": " + request.getAudioFcc()); } } } }