private XmlNode CreateDocTitle(XmlDocument ncxDocument, XmlNode ncxRootNode, TreeNode n, TreeNode levelNode) { XmlNode docNode = ncxDocument.CreateElement(null, "docTitle", ncxRootNode.NamespaceURI); XmlNode navMapNode = XmlDocumentHelper.GetFirstChildElementOrSelfWithName(ncxDocument, true, "navMap", null); ncxRootNode.InsertBefore(docNode, navMapNode); XmlNode docTxtNode = ncxDocument.CreateElement(null, "text", docNode.NamespaceURI); docNode.AppendChild(docTxtNode); docTxtNode.AppendChild( ncxDocument.CreateTextNode(prepareNcxLabelText(n))); ExternalAudioMedia externalAudio = GetExternalAudioMedia(n); if (externalAudio != null) { // create audio node XmlNode docAudioNode = ncxDocument.CreateElement(null, "audio", docNode.NamespaceURI); docNode.AppendChild(docAudioNode); XmlDocumentHelper.CreateAppendXmlAttribute(ncxDocument, docAudioNode, "clipBegin", FormatTimeString(externalAudio.ClipBegin)); XmlDocumentHelper.CreateAppendXmlAttribute(ncxDocument, docAudioNode, "clipEnd", FormatTimeString(externalAudio.ClipEnd)); string extAudioSrc = AdjustAudioFileName(externalAudio, levelNode); XmlDocumentHelper.CreateAppendXmlAttribute(ncxDocument, docAudioNode, "src", FileDataProvider.UriEncode(Path.GetFileName(extAudioSrc))); } return(docNode); }
public void checkAudioMediaStaticProperties() { ExternalAudioMedia obj = factory.Create <ExternalAudioMedia>(); Assert.AreEqual(obj.IsContinuous, true); Assert.AreEqual(obj.IsDiscrete, false); Assert.AreEqual(obj.IsSequence, false); }
public void CheckAudioDuration_SimpleMS() { ExternalAudioMedia audio = factory.Create <ExternalAudioMedia>(); audio.ClipBegin = new Time(0); audio.ClipEnd = new Time(1000); TimeDelta td = (TimeDelta)audio.Duration; Assert.AreEqual(1000, td.TimeDeltaAsMillisecondLong); }
public void checkAudioMediaCopy() { ExternalAudioMedia audio = factory.Create <ExternalAudioMedia>(); bool exceptionOccured = false; try { Media audio_copy = ((Media)audio).Copy(); } catch (exception.OperationNotValidException) { exceptionOccured = true; } Assert.IsFalse( exceptionOccured, "Media.copy() method was probably not overridden in AbstractAudioMedia subclass of ExternalMedia"); }
public void SplitAudioObjectCheckNewTimes_SimpleMS() { ExternalAudioMedia obj = factory.Create <ExternalAudioMedia>(); obj.ClipBegin = new Time(0); obj.ClipEnd = new Time(1000); ExternalAudioMedia new_obj = obj.Split(new Time(600)); //check begin/end times for original node Time t = (Time)obj.ClipBegin; Assert.AreEqual(0, t.TimeAsMillisecondLong); t = (Time)obj.ClipEnd; Assert.AreEqual(600, t.TimeAsMillisecondLong); //check begin/end times for newly created node t = (Time)new_obj.ClipBegin; Assert.AreEqual(600, t.TimeAsMillisecondLong); t = (Time)new_obj.ClipEnd; Assert.AreEqual(1000, t.TimeAsMillisecondLong); }
private XmlNode CreateNavPointWithoutContentNode(XmlDocument ncxDocument, TreeNode urakawaNode, TreeNode currentHeadingTreeNode, TreeNode n, Dictionary <TreeNode, XmlNode> treeNode_NavNodeMap) { XmlNode navMapNode = ncxDocument.GetElementsByTagName("navMap")[0]; ExternalAudioMedia externalAudio = GetExternalAudioMedia(n); // first create navPoints XmlNode navPointNode = ncxDocument.CreateElement(null, "navPoint", navMapNode.NamespaceURI); if (currentHeadingTreeNode != null) { XmlDocumentHelper.CreateAppendXmlAttribute(ncxDocument, navPointNode, "class", currentHeadingTreeNode.GetXmlProperty().LocalName); } XmlDocumentHelper.CreateAppendXmlAttribute(ncxDocument, navPointNode, "id", GetNextID(ID_NcxPrefix)); XmlDocumentHelper.CreateAppendXmlAttribute(ncxDocument, navPointNode, "playOrder", ""); TreeNode parentNode = GetParentLevelNode(urakawaNode); if (parentNode == null) { navMapNode.AppendChild(navPointNode); } else { XmlNode obj; treeNode_NavNodeMap.TryGetValue(parentNode, out obj); if (obj != null) //treeNode_NavNodeMap.ContainsKey(parentNode)) { obj.AppendChild(navPointNode); //treeNode_NavNodeMap[parentNode] } else // surch up for node { int counter = 0; while (parentNode != null && counter <= 6) { parentNode = GetParentLevelNode(parentNode); if (parentNode != null //&& treeNode_NavNodeMap.ContainsKey(parentNode) ) { treeNode_NavNodeMap.TryGetValue(parentNode, out obj); if (obj != null) { obj.AppendChild(navPointNode); //treeNode_NavNodeMap[parentNode] break; } } counter++; } if (parentNode == null || counter > 7) { navMapNode.AppendChild(navPointNode); } } } treeNode_NavNodeMap.Add(urakawaNode, navPointNode); // create navLabel XmlNode navLabel = ncxDocument.CreateElement(null, "navLabel", navPointNode.NamespaceURI); navPointNode.AppendChild(navLabel); // create text node XmlNode txtNode = ncxDocument.CreateElement(null, "text", navMapNode.NamespaceURI); navLabel.AppendChild(txtNode); if (currentHeadingTreeNode != null) { txtNode.AppendChild( ncxDocument.CreateTextNode(prepareNcxLabelText(n))); } if (externalAudio != null) { // create audio node XmlNode audioNode = ncxDocument.CreateElement(null, "audio", navMapNode.NamespaceURI); navLabel.AppendChild(audioNode); XmlDocumentHelper.CreateAppendXmlAttribute(ncxDocument, audioNode, "clipBegin", FormatTimeString(externalAudio.ClipBegin)); XmlDocumentHelper.CreateAppendXmlAttribute(ncxDocument, audioNode, "clipEnd", FormatTimeString(externalAudio.ClipEnd)); string extAudioSrc = AdjustAudioFileName(externalAudio, urakawaNode); XmlDocumentHelper.CreateAppendXmlAttribute(ncxDocument, audioNode, "src", FileDataProvider.UriEncode(Path.GetFileName(extAudioSrc))); } return(navPointNode); }
private void verifyTree(TreeNode node, bool ancestorHasAudio, string ancestorExtAudioFile) { if (TreeNodeMustBeSkipped(node)) { return; } if (TreeNodeTriggersNewAudioFile(node) && ancestorExtAudioFile == null) { ancestorExtAudioFile = ""; } Media manSeqMedia = node.GetManagedAudioMediaOrSequenceMedia(); if (ancestorHasAudio) { DebugFix.Assert(manSeqMedia == null); } if (node.HasChannelsProperty) { ChannelsProperty chProp = node.GetChannelsProperty(); Media media = chProp.GetMedia(DestinationChannel); if (ancestorHasAudio) { DebugFix.Assert(media == null); } if (media != null) { DebugFix.Assert(media is ExternalAudioMedia); DebugFix.Assert(manSeqMedia != null); if (!ancestorHasAudio) { ExternalAudioMedia extMedia = (ExternalAudioMedia)media; ancestorHasAudio = true; if (ancestorExtAudioFile != null) { if (ancestorExtAudioFile == "") { ancestorExtAudioFile = extMedia.Uri.LocalPath; } else { DebugFix.Assert(ancestorExtAudioFile == extMedia.Uri.LocalPath); } } else { ancestorExtAudioFile = extMedia.Uri.LocalPath; } string ext = Path.GetExtension(ancestorExtAudioFile); if (!DataProviderFactory.AUDIO_WAV_EXTENSION.Equals(ext, StringComparison.OrdinalIgnoreCase)) { Debug.Fail("Verification can only be done if external media points to wav file!"); } //reportProgress(-1, @"DEBUG: " + ancestorExtAudioFile); Stream extMediaStream = new FileStream(ancestorExtAudioFile, FileMode.Open, FileAccess.Read, FileShare.None); Stream manMediaStream = null; ManagedAudioMedia manMedia = node.GetManagedAudioMedia(); #if ENABLE_SEQ_MEDIA SequenceMedia seqMedia = node.GetManagedAudioSequenceMedia(); #endif //ENABLE_SEQ_MEDIA if (manMedia != null) { #if ENABLE_SEQ_MEDIA DebugFix.Assert(seqMedia == null); #endif //ENABLE_SEQ_MEDIA DebugFix.Assert(manMedia.HasActualAudioMediaData); manMediaStream = manMedia.AudioMediaData.OpenPcmInputStream(); } else { Debug.Fail("SequenceMedia is normally removed at import time...have you tried re-importing the DAISY book ?"); #if ENABLE_SEQ_MEDIA DebugFix.Assert(seqMedia != null); DebugFix.Assert(!seqMedia.AllowMultipleTypes); DebugFix.Assert(seqMedia.ChildMedias.Count > 0); DebugFix.Assert(seqMedia.ChildMedias.Get(0) is ManagedAudioMedia); manMediaStream = seqMedia.OpenPcmInputStreamOfManagedAudioMedia(); #endif //ENABLE_SEQ_MEDIA } try { uint extMediaPcmLength; AudioLibPCMFormat pcmInfo = AudioLibPCMFormat.RiffHeaderParse(extMediaStream, out extMediaPcmLength); DebugFix.Assert(extMediaPcmLength == extMediaStream.Length - extMediaStream.Position); if (manMedia != null) { DebugFix.Assert(pcmInfo.IsCompatibleWith(manMedia.AudioMediaData.PCMFormat.Data)); } #if ENABLE_SEQ_MEDIA if (seqMedia != null) { DebugFix.Assert( pcmInfo.IsCompatibleWith( ((ManagedAudioMedia)seqMedia.ChildMedias.Get(0)).AudioMediaData.PCMFormat.Data)); } #endif //ENABLE_SEQ_MEDIA extMediaStream.Position += pcmInfo.ConvertTimeToBytes(extMedia.ClipBegin.AsLocalUnits); long manMediaStreamPosBefore = manMediaStream.Position; long extMediaStreamPosBefore = extMediaStream.Position; //DebugFix.Assert(AudioLibPCMFormat.CompareStreamData(manMediaStream, extMediaStream, (int)manMediaStream.Length)); //DebugFix.Assert(manMediaStream.Position == manMediaStreamPosBefore + manMediaStream.Length); //DebugFix.Assert(extMediaStream.Position == extMediaStreamPosBefore + manMediaStream.Length); } finally { extMediaStream.Close(); manMediaStream.Close(); } } } else { DebugFix.Assert(manSeqMedia == null); } } else { DebugFix.Assert(manSeqMedia == null); } foreach (TreeNode child in node.Children.ContentsAs_Enumerable) { verifyTree(child, ancestorHasAudio, ancestorExtAudioFile); } }
protected string AdjustAudioFileName(ExternalAudioMedia externalAudio, TreeNode levelNode) { //#if !TOBI // // Obi should not use this, as the above AddSectionNameToAudioFileName() is used instead!! // Debugger.Break(); // return externalAudio.Src; //#endif // Obi should return below! if (!IsAdjustAudioFileNameEnabled) { return(externalAudio.Src); } if (externalAudio.Tag == null || !(externalAudio.Tag is TreeNode)) { #if DEBUG Debugger.Break(); #endif return(externalAudio.Src); } TreeNode node = externalAudio.Tag as TreeNode; // In some cases this occurs (for example with Great Painters, // or when m_audioExportDTBOOKElementNameTriggers / doesTreeNodeTriggerNewSmil() is set to level2 but not level1 // The generated SMIL and audio file structure looks okay, but the heading/section title is missing in the filename // DebugFix.Assert(node == levelNode); #if DEBUG if (node != levelNode) { bool breakpointHere = true; } // Debugger.Break(); #endif string src = null; m_adjustedExternalAudioFileNames.TryGetValue(node, out src); if (!string.IsNullOrEmpty(src)) { #if DEBUG //DebugFix.Assert(!src.Equals(externalAudio.Src, StringComparison.Ordinal)); //if (src.Equals(externalAudio.Src, StringComparison.Ordinal)) //{ // Debugger.Break(); //} #endif externalAudio.Src = src; return(src); } string strTitle = ""; bool html5_outlining = node.Presentation.RootNode.GetXmlElementLocalName() .Equals("body", StringComparison.OrdinalIgnoreCase); if (html5_outlining) { #if DEBUG Debugger.Break(); #endif //TODO? //List<Section> sections = node.Presentation.RootNode.GetOrCreateOutline() // spine item / HTML title?? } else { string localName = node.GetXmlElementLocalName(); #if DEBUG //protected virtual bool doesTreeNodeTriggerNewSmil(TreeNode node) DebugFix.Assert(node.HasXmlProperty); DebugFix.Assert(localName.StartsWith("level", StringComparison.OrdinalIgnoreCase) || localName.Equals("section", StringComparison.OrdinalIgnoreCase) || localName.Equals("book", StringComparison.OrdinalIgnoreCase) ); #endif TreeNode heading = null; if (TreeNode.IsLevel(localName)) { TreeNode level = node; if (level.Children.Count > 0) { TreeNode nd = level.Children.Get(0); if (nd != null) { localName = nd.HasXmlProperty ? nd.GetXmlElementLocalName() : null; if (localName != null && (localName == "pagenum" || localName == "img") && level.Children.Count > 1) { nd = level.Children.Get(1); if (nd != null) { localName = nd.GetXmlElementLocalName(); } } if (localName != null && (TreeNode.IsHeading(localName))) { heading = nd; } else { if (localName != null && (localName == "pagenum" || localName == "img") && level.Children.Count > 2) { nd = level.Children.Get(2); if (nd != null) { localName = nd.GetXmlElementLocalName(); } } if (localName != null && (TreeNode.IsHeading(localName))) { heading = nd; } } } } } else if (TreeNode.IsHeading(localName)) { #if DEBUG Debugger.Break(); #endif heading = node; } else if (!localName.Equals("book", StringComparison.OrdinalIgnoreCase)) { #if DEBUG Debugger.Break(); #endif } StringBuilder strBuilder = null; if (heading != null) { TreeNode.StringChunkRange range = heading.GetTextFlattened_(); if (!(range == null || range.First == null || string.IsNullOrEmpty(range.First.Str))) { strBuilder = new StringBuilder(range.GetLength()); TreeNode.ConcatStringChunks(range, -1, strBuilder); //strBuilder.Insert(0, "] "); //strBuilder.Insert(0, heading.GetXmlElementLocalName()); //strBuilder.Insert(0, "["); } } //else //{ // strBuilder = new StringBuilder(); // strBuilder.Append("["); // strBuilder.Append(level.GetXmlElementLocalName()); // strBuilder.Append("] "); // strBuilder.Append(Tobi_Plugin_NavigationPane_Lang.NoHeading); //} if (strBuilder != null) { strTitle = strBuilder.ToString().Trim(); } } if (strTitle.Length > 0) { strTitle = FileDataProvider.EliminateForbiddenFileNameCharacters(strTitle.Replace(" ", "_")); } int MAX_LENGTH = AudioFileNameCharsLimit > 0 ? AudioFileNameCharsLimit : 10; if (strTitle.Length > MAX_LENGTH) { strTitle = strTitle.Substring(0, MAX_LENGTH); } string filename = Path.GetFileName(externalAudio.Src); string source = Path.Combine(m_OutputDirectory, filename); if (File.Exists(source)) { if (strTitle.Length > 0) { string newFileName = filename; string name = Path.GetFileNameWithoutExtension(externalAudio.Src); name = name.Replace("aud", ""); string ext = Path.GetExtension(externalAudio.Src); newFileName = name + "_" + strTitle + ext; //externalAudio.Src = externalAudio.Src.Replace(filename, newFileName); externalAudio.Src = newFileName; m_adjustedExternalAudioFileNames.Add(node, externalAudio.Src); string dest = Path.Combine(m_OutputDirectory, newFileName); File.Move(source, dest); try { File.SetAttributes(dest, FileAttributes.Normal); } catch { } return(newFileName); } } return(filename); }
public override bool PreVisit(TreeNode node) { if (m_RootNode == null) { m_RootNode = node; } if (m_currentAudioLevelNode == null) { m_currentAudioLevelNode = m_RootNode; } if (TreeNodeMustBeSkipped(node)) { return(false); } if (RequestCancellation) { checkTransientWavFileAndClose(node); return(false); } if (TreeNodeTriggersNewAudioFile(node)) { m_currentAudioLevelNode = node; checkTransientWavFileAndClose(node); // REMOVED, because doesn't support nested TreeNode matches ! return false; // skips children, see postVisit } if (node.GetAlternateContentProperty() != null) { m_AlternateContentPropertiesList.Add(node.GetAlternateContentProperty()); } if (!node.HasChannelsProperty) { return(true); } if (!node.Presentation.MediaDataManager.EnforceSinglePCMFormat) { Debug.Fail("! EnforceSinglePCMFormat ???"); throw new Exception("! EnforceSinglePCMFormat ???"); } #if ENABLE_SEQ_MEDIA Media media = node.GetManagedAudioMediaOrSequenceMedia(); if (media == null) { return(true); } #endif ManagedAudioMedia manAudioMedia = node.GetManagedAudioMedia(); if (manAudioMedia == null) { return(true); } //if (!manAudioMedia.HasActualAudioMediaData) //{ // return true; //} if (m_TransientWavFileStream == null) { mCurrentAudioFileNumber++; Uri waveFileUri = GetCurrentAudioFileUri(); m_TransientWavFileStream = new FileStream(waveFileUri.LocalPath, FileMode.Create, FileAccess.Write, FileShare.None); m_TransientWavFileStreamRiffOffset = node.Presentation.MediaDataManager.DefaultPCMFormat.Data.RiffHeaderWrite(m_TransientWavFileStream, 0); } long bytesBegin = m_TransientWavFileStream.Position - (long)m_TransientWavFileStreamRiffOffset; #if ENABLE_SEQ_MEDIA SequenceMedia seqAudioMedia = node.GetManagedAudioSequenceMedia(); #endif //ENABLE_SEQ_MEDIA Stream audioPcmStream = null; if (manAudioMedia != null) { audioPcmStream = manAudioMedia.AudioMediaData.OpenPcmInputStream(); } #if ENABLE_SEQ_MEDIA else if (seqAudioMedia != null) { Debug.Fail("SequenceMedia is normally removed at import time...have you tried re-importing the DAISY book ?"); audioPcmStream = seqAudioMedia.OpenPcmInputStreamOfManagedAudioMedia(); } #endif //ENABLE_SEQ_MEDIA else { Debug.Fail("This should never happen !!"); return(false); } if (RequestCancellation) { checkTransientWavFileAndClose(node); return(false); } try { const uint BUFFER_SIZE = 1024 * 1024 * 3; // 3 MB MAX BUFFER uint streamCount = StreamUtils.Copy(audioPcmStream, 0, m_TransientWavFileStream, BUFFER_SIZE); //System.Windows.Forms.MessageBox.Show ( audioPcmStream.Length.ToString () + " : " + m_TransientWavFileStream.Length.ToString () + " : " + streamCount.ToString () ); } catch { m_TransientWavFileStream.Close(); m_TransientWavFileStream = null; m_TransientWavFileStreamRiffOffset = 0; #if DEBUG Debugger.Break(); #endif } finally { audioPcmStream.Close(); } if (m_TransientWavFileStream == null) { Debug.Fail("Stream copy error !!"); return(false); } long bytesEnd = m_TransientWavFileStream.Position - (long)m_TransientWavFileStreamRiffOffset; string src = node.Presentation.RootUri.MakeRelativeUri(GetCurrentAudioFileUri()).ToString(); if (manAudioMedia != null #if ENABLE_SEQ_MEDIA || seqAudioMedia != null #endif //ENABLE_SEQ_MEDIA ) { if (m_TotalTimeInLocalUnits == 0) { Time dur = node.Root.GetDurationOfManagedAudioMediaFlattened(); if (dur != null) { m_TotalTimeInLocalUnits = dur.AsLocalUnits; } } m_TimeElapsedInLocalUnits += manAudioMedia != null ? manAudioMedia.Duration.AsLocalUnits : #if ENABLE_SEQ_MEDIA seqAudioMedia.GetDurationOfManagedAudioMedia().AsLocalUnits #else -1 #endif //ENABLE_SEQ_MEDIA ; int percent = Convert.ToInt32((m_TimeElapsedInLocalUnits * 100) / m_TotalTimeInLocalUnits); if (EncodePublishedAudioFiles) { reportProgress_Throttle(percent, String.Format(UrakawaSDK_daisy_Lang.CreateMP3File, Path.GetFileName(src).Replace(DataProviderFactory.AUDIO_WAV_EXTENSION, DataProviderFactory.AUDIO_MP3_EXTENSION), GetSizeInfo(node))); } else { reportProgress_Throttle(percent, String.Format(UrakawaSDK_daisy_Lang.CreatingAudioFile, Path.GetFileName(src), GetSizeInfo(node))); } //Console.WriteLine("progress percent " + m_ProgressPercentage); } ExternalAudioMedia extAudioMedia = node.Presentation.MediaFactory.Create <ExternalAudioMedia>(); extAudioMedia.Tag = m_currentAudioLevelNode; ushort nChannels = (ushort)(EncodePublishedAudioFilesStereo ? 2 : 1); if ((EncodePublishedAudioFiles || (ushort)EncodePublishedAudioFilesSampleRate != node.Presentation.MediaDataManager.DefaultPCMFormat.Data.SampleRate || nChannels != node.Presentation.MediaDataManager.DefaultPCMFormat.Data.NumberOfChannels ) && !m_ExternalAudioMediaList.Contains(extAudioMedia)) { m_ExternalAudioMediaList.Add(extAudioMedia); } extAudioMedia.Language = node.Presentation.Language; extAudioMedia.Src = src; long timeBegin = node.Presentation.MediaDataManager.DefaultPCMFormat.Data.ConvertBytesToTime(bytesBegin); long timeEnd = node.Presentation.MediaDataManager.DefaultPCMFormat.Data.ConvertBytesToTime(bytesEnd); extAudioMedia.ClipBegin = new Time(timeBegin); extAudioMedia.ClipEnd = new Time(timeEnd); ChannelsProperty chProp = node.GetChannelsProperty(); if (chProp.GetMedia(DestinationChannel) != null) { chProp.SetMedia(DestinationChannel, null); Debug.Fail("This should never happen !!"); } chProp.SetMedia(DestinationChannel, extAudioMedia); return(false); }
private void EncodeTransientFileToMp4OrAMR(TreeNode node) { ExternalAudioMedia extMedia = m_ExternalAudioMediaList[0]; AudioLib.WavFormatConverter formatConverter = new WavFormatConverter(true, DisableAcmCodecs); string sourceFilePath = base.GetCurrentAudioFileUri().LocalPath; string extension = EncodingFileFormat == AudioFileFormats.MP4 ? DataProviderFactory.AUDIO_MP4_EXTENSION : EncodingFileFormat == AudioFileFormats.AMR ? DataProviderFactory.AUDIO_AMR_EXTENSION : DataProviderFactory.AUDIO_3GPP_EXTENSION; string destinationFilePath = Path.Combine(base.DestinationDirectory.LocalPath, Path.GetFileNameWithoutExtension(sourceFilePath) + extension); //reportProgress(m_ProgressPercentage, String.Format(UrakawaSDK_daisy_Lang.CreateMP3File, Path.GetFileName(destinationFilePath), GetSizeInfo(m_RootNode))); PCMFormatInfo audioFormat = extMedia.Presentation.MediaDataManager.DefaultPCMFormat; //AudioLibPCMFormat pcmFormat = audioFormat.Data; AudioLibPCMFormat pcmFormat = new AudioLibPCMFormat(); pcmFormat.CopyFrom(audioFormat.Data); pcmFormat.SampleRate = (ushort)base.EncodePublishedAudioFilesSampleRate; pcmFormat.NumberOfChannels = (ushort)(base.EncodePublishedAudioFilesStereo ? 2 : 1); AddSubCancellable(formatConverter); bool result = false; try { result = formatConverter.CompressWavToMP4And3GP(sourceFilePath, destinationFilePath, pcmFormat, BitRate_Encoding); } finally { RemoveSubCancellable(formatConverter); } if (RequestCancellation) { m_ExternalAudioMediaList.Clear(); return; } if (result) { m_EncodingFileCompressionRatio = (new FileInfo(sourceFilePath).Length) / (new FileInfo(destinationFilePath).Length); foreach (ExternalAudioMedia ext in m_ExternalAudioMediaList) { if (ext != null) { ext.Src = ext.Src.Replace(DataProviderFactory.AUDIO_WAV_EXTENSION, extension); } } File.Delete(sourceFilePath); } else { // append error messages base.ErrorMessages = base.ErrorMessages + String.Format(UrakawaSDK_daisy_Lang.ErrorInEncoding, Path.GetFileName(sourceFilePath)); } m_ExternalAudioMediaList.Clear(); }
private void EncodeTransientFileResample(TreeNode node) { string sourceFilePath = base.GetCurrentAudioFileUri().LocalPath; //string destinationFilePath = Path.Combine(base.DestinationDirectory.LocalPath, Path.GetFileNameWithoutExtension(sourceFilePath) + "_" + base.EncodePublishedAudioFilesSampleRate + DataProviderFactory.AUDIO_WAV_EXTENSION); //reportProgress(m_ProgressPercentage, String.Format(UrakawaSDK_daisy_Lang.ConvertingAudio,sourceFilePath)); ExternalAudioMedia extMedia = m_ExternalAudioMediaList[0]; PCMFormatInfo audioFormat = extMedia.Presentation.MediaDataManager.DefaultPCMFormat; //AudioLibPCMFormat pcmFormat = audioFormat.Data; AudioLibPCMFormat pcmFormat = new AudioLibPCMFormat(); pcmFormat.CopyFrom(audioFormat.Data); pcmFormat.SampleRate = (ushort)base.EncodePublishedAudioFilesSampleRate; pcmFormat.NumberOfChannels = (ushort)(base.EncodePublishedAudioFilesStereo ? 2 : 1); AudioLib.WavFormatConverter formatConverter = new WavFormatConverter(true, DisableAcmCodecs); AddSubCancellable(formatConverter); string destinationFilePath = null; try { AudioLibPCMFormat originalPcmFormat; destinationFilePath = formatConverter.ConvertSampleRate(sourceFilePath, base.DestinationDirectory.LocalPath, pcmFormat, out originalPcmFormat); if (originalPcmFormat != null) { DebugFix.Assert(audioFormat.Data.Equals(originalPcmFormat)); } } finally { RemoveSubCancellable(formatConverter); } //string sourceName = Path.GetFileNameWithoutExtension(sourceFilePath); //string destName = Path.GetFileNameWithoutExtension(destinationFilePath); //foreach (ExternalAudioMedia ext in m_ExternalAudioMediaList) //{ //if (ext != null) //{ //ext.Src = ext.Src.Replace(sourceName, destName); //} //} File.Delete(sourceFilePath); File.Move(destinationFilePath, sourceFilePath); try { File.SetAttributes(sourceFilePath, FileAttributes.Normal); } catch { } m_ExternalAudioMediaList.Clear(); }
// to do regenerate ids private void CreateDTBookDocument() { // check if there is preserved internal DTD string [] dtbFilesList = Directory.GetFiles(m_Presentation.DataProviderManager.DataFileDirectoryFullPath, "DTBookLocalDTD.dtd", SearchOption.AllDirectories); string strInternalDTD = null; if (dtbFilesList.Length > 0) { strInternalDTD = File.ReadAllText(dtbFilesList[0]); if (strInternalDTD.Trim() == "") { strInternalDTD = null; } } XmlDocument DTBookDocument = CreateStub_DTBDocument(strInternalDTD); m_ListOfLevels = new List <urakawa.core.TreeNode>(); Dictionary <string, string> old_New_IDMap = new Dictionary <string, string> (); List <XmlAttribute> referencingAttributesList = new List <XmlAttribute> (); m_FilesList_Image = new List <string>(); // add metadata XmlNode headNode = getFirstChildElementsWithName(DTBookDocument, true, "head", null); //DTBookDocument.GetElementsByTagName("head")[0] Metadata mdId = AddMetadata_DtbUid(false, DTBookDocument, headNode); AddMetadata_Generator(DTBookDocument, headNode); // todo: filter-out unecessary metadata for DTBOOK (e.g. dtb:multimediatype) foreach (urakawa.metadata.Metadata m in m_Presentation.Metadatas.ContentsAs_YieldEnumerable) { if (mdId == m) { continue; } XmlNode metaNode = DTBookDocument.CreateElement(null, "meta", headNode.NamespaceURI); headNode.AppendChild(metaNode); string name = m.NameContentAttribute.Name; if (name.Contains(":")) { // split the metadata name and make first alphabet upper, required for daisy 3.0 string splittedName = name.Split(':')[1]; splittedName = splittedName.Substring(0, 1).ToUpper() + splittedName.Remove(0, 1); name = name.Split(':')[0] + ":" + splittedName; } CommonFunctions.CreateAppendXmlAttribute(DTBookDocument, metaNode, "name", name); CommonFunctions.CreateAppendXmlAttribute(DTBookDocument, metaNode, "content", m.NameContentAttribute.Value); // add metadata optional attributes if any foreach (urakawa.metadata.MetadataAttribute ma in m.OtherAttributes.ContentsAs_YieldEnumerable) { if (ma.Name == "id") { continue; } CommonFunctions.CreateAppendXmlAttribute(DTBookDocument, metaNode, ma.Name, ma.Value); } } // add elements to book body m_TreeNode_XmlNodeMap = new Dictionary <urakawa.core.TreeNode, XmlNode>(); urakawa.core.TreeNode rNode = m_Presentation.RootNode; XmlNode bookNode = getFirstChildElementsWithName(DTBookDocument, true, "book", null); //DTBookDocument.GetElementsByTagName("book")[0]; m_ListOfLevels.Add(m_Presentation.RootNode); m_TreeNode_XmlNodeMap.Add(rNode, bookNode); XmlNode currentXmlNode = null; rNode.AcceptDepthFirst( delegate(urakawa.core.TreeNode n) { // add to list of levels if xml property has level string //QualifiedName qName = n.GetXmlElementQName(); //if (qName != null && // (qName.LocalName.StartsWith("level") || qName.LocalName == "doctitle" || qName.LocalName == "docauthor")) //{ // m_ListOfLevels.Add(n); //} if (doesTreeNodeTriggerNewSmil(n)) { m_ListOfLevels.Add(n); } urakawa.property.xml.XmlProperty xmlProp = n.GetProperty <urakawa.property.xml.XmlProperty>(); if (xmlProp != null && xmlProp.LocalName == "book") { return(true); } if (xmlProp == null) { string txtx = n.GetTextMedia() != null ? n.GetTextMedia().Text : null; if (txtx != null) { XmlNode textNode = DTBookDocument.CreateTextNode(txtx); ExternalAudioMedia extAudio = GetExternalAudioMedia(n); if (extAudio == null) { m_TreeNode_XmlNodeMap[n.Parent].AppendChild(textNode); m_TreeNode_XmlNodeMap.Add(n, textNode); } else { Debug.Fail("TreeNode without XmlProperty but with TextMedia cannot have Audio attached to it ! (reason: at authoring time, an XmlProperty should have been added when audio was recorded for the pure-text TreeNode) => " + txtx); //XmlNode textParent = DTBookDocument.CreateElement(null, "sent", bookNode.NamespaceURI); //textParent.AppendChild(textNode); //m_TreeNode_XmlNodeMap[n.Parent].AppendChild(textParent); //m_TreeNode_XmlNodeMap.Add(n, textParent); } } return(true); } // create sml node in dtbook document // code removed because XmlProperty stores proper namespaces, useful for inline MathML, SVG, whatever... //string name = xmlProp.LocalName; //string prefix = name.Contains(":") ? name.Split(':')[0] : null; //string elementName = name.Contains(":") ? name.Split(':')[1] : name; //currentXmlNode = DTBookDocument.CreateElement(prefix, elementName, bookNode.NamespaceURI); currentXmlNode = DTBookDocument.CreateElement(null, xmlProp.LocalName, (string.IsNullOrEmpty(xmlProp.NamespaceUri) ? bookNode.NamespaceURI : xmlProp.NamespaceUri)); // add attributes if (xmlProp.Attributes != null && xmlProp.Attributes.Count > 0) { for (int i = 0; i < xmlProp.Attributes.Count; i++) { //todo: check ID attribute, normalize with fresh new list of IDs // (warning: be careful maintaining ID REFS, such as idref attributes for annotation/annoref and prodnote/noteref // (be careful because idref contain URIs with hash character), // and also the special imgref and headers attributes which contain space-separated list of IDs, not URIs) if (xmlProp.Attributes[i].LocalName == "id") { string id_New = GetNextID(ID_DTBPrefix); CommonFunctions.CreateAppendXmlAttribute(DTBookDocument, currentXmlNode, "id", id_New); if (!old_New_IDMap.ContainsKey(xmlProp.Attributes[i].Value)) { old_New_IDMap.Add(xmlProp.Attributes[i].Value, id_New); } else { System.Diagnostics.Debug.Fail("Duplicate ID found in original DTBook document", "Original DTBook document has duplicate ID: " + xmlProp.Attributes[i].Value); } } else { CommonFunctions.CreateAppendXmlAttribute(DTBookDocument, currentXmlNode, xmlProp.Attributes[i].LocalName, xmlProp.Attributes[i].Value); } } // for loop ends } // attribute nodes created // add id attribute in case it do not exists and it is required if (currentXmlNode.Attributes.GetNamedItem("id") == null && IsIDRequired(currentXmlNode.LocalName)) { CommonFunctions.CreateAppendXmlAttribute(DTBookDocument, currentXmlNode, "id", GetNextID(ID_DTBPrefix)); } // add text from text property string txt = n.GetTextMedia() != null ? n.GetTextMedia().Text : null; if (txt != null) { XmlNode textNode = DTBookDocument.CreateTextNode(txt); currentXmlNode.AppendChild(textNode); Debug.Assert(n.Children.Count == 0); } // add current node to its parent m_TreeNode_XmlNodeMap[n.Parent].AppendChild(currentXmlNode); // add nodes to dictionary m_TreeNode_XmlNodeMap.Add(n, currentXmlNode); // if current xmlnode is referencing node, add its referencing attribute to referencingAttributesList AddReferencingNodeToReferencedAttributesList(currentXmlNode, referencingAttributesList); // if QName is img and img src is on disk, copy it to output dir if (currentXmlNode.LocalName == "img") { XmlAttribute imgSrcAttribute = (XmlAttribute)currentXmlNode.Attributes.GetNamedItem("src"); if (imgSrcAttribute != null && (imgSrcAttribute.Value.StartsWith(m_Presentation.DataProviderManager.DataFileDirectory))) { string imgFileName = Path.GetFileName(imgSrcAttribute.Value); string sourcePath = Path.Combine(m_Presentation.DataProviderManager.DataFileDirectoryFullPath, Uri.UnescapeDataString(imgFileName)); string destPath = Path.Combine(m_OutputDirectory, Uri.UnescapeDataString(imgFileName)); if (File.Exists(sourcePath)) { if (!File.Exists(destPath)) { File.Copy(sourcePath, destPath); } imgSrcAttribute.Value = imgFileName; if (!m_FilesList_Image.Contains(imgFileName)) { m_FilesList_Image.Add(imgFileName); } } else { System.Diagnostics.Debug.Fail("source image not found", sourcePath); } } } return(true); }, delegate(urakawa.core.TreeNode n) { }); // set references to new ids foreach (XmlAttribute attr in referencingAttributesList) { string strIDToFind = attr.Value; if (strIDToFind.Contains("#")) { strIDToFind = strIDToFind.Split('#')[1]; } if (old_New_IDMap.ContainsKey(strIDToFind)) { string id_New = old_New_IDMap[strIDToFind]; attr.Value = "#" + id_New; } } m_DTBDocument = DTBookDocument; //CommonFunctions.WriteXmlDocumentToFile(DTBookDocument, // Path.Combine(m_OutputDirectory, m_Filename_Content)); }
public override bool PreVisit(TreeNode node) { if (m_RootNode == null) { m_RootNode = node; } if (TreeNodeMustBeSkipped(node)) { return(false); } if (TreeNodeTriggersNewAudioFile(node)) { createNextAudioFile(node); } if (node.HasProperties(typeof(ChannelsProperty))) { ChannelsProperty chProp = node.GetChannelsProperty(); ManagedAudioMedia mam = chProp.GetMedia(SourceChannel) as ManagedAudioMedia; if (mam != null) { AudioMediaData amd = mam.AudioMediaData; if (mCurrentAudioFileStream == null) { createNextAudioFile(node); } else if (mCurrentAudioFilePCMFormat != null && !mCurrentAudioFilePCMFormat.Data.IsCompatibleWith(amd.PCMFormat.Data)) { #if DEBUG Debugger.Break(); #endif createNextAudioFile(node); } if (mCurrentAudioFileStream != null && mCurrentAudioFilePCMFormat == null) { writeInitialHeader(amd.PCMFormat); } Time durationFromRiffHeader = amd.AudioDuration; Time clipBegin = new Time(mCurrentAudioFilePCMFormat.Data.ConvertBytesToTime(mCurrentAudioFileStream.Position - mCurrentAudioFileStreamRiffWaveHeaderLength)); Time clipEnd = new Time(clipBegin.AsTimeSpanTicks + durationFromRiffHeader.AsTimeSpanTicks, true); //BinaryReader rd = new BinaryReader(stream); Stream stream = amd.OpenPcmInputStream(); try { const uint BUFFER_SIZE = 1024 * 1024 * 3; // 3 MB MAX BUFFER StreamUtils.Copy(stream, 0, mCurrentAudioFileStream, BUFFER_SIZE); } finally { stream.Close(); } ExternalAudioMedia eam = node.Presentation.MediaFactory.Create <ExternalAudioMedia>(); if (eam == null) { throw new exception.FactoryCannotCreateTypeException(String.Format( "The media facotry cannot create a ExternalAudioMedia matching QName {1}:{0}", XukAble.GetXukName(typeof(ExternalAudioMedia), true) ?? typeof(ExternalAudioMedia).Name, node.Presentation.Project.GetXukNamespace())); } eam.Language = mam.Language; eam.Src = node.Presentation.RootUri.MakeRelativeUri(GetCurrentAudioFileUri()).ToString(); eam.ClipBegin = clipBegin; eam.ClipEnd = clipEnd; if (chProp.GetMedia(DestinationChannel) != null) { #if DEBUG Debugger.Break(); #endif chProp.SetMedia(DestinationChannel, null); } chProp.SetMedia(DestinationChannel, eam); } } return(true); }
private void CreateElementsForSection(XmlDocument nccDocument, SectionNode section, int sectionIndex) { Time sectionDuration = new Time(); string nccFileName = "ncc.html"; XmlNode bodyNode = nccDocument.GetElementsByTagName("body")[0]; XmlNode headingNode = nccDocument.CreateElement(null, "h" + section.Level.ToString(), bodyNode.NamespaceURI); if (sectionIndex == 0) { CreateAppendXmlAttribute(nccDocument, headingNode, "class", "title"); } else { CreateAppendXmlAttribute(nccDocument, headingNode, "class", "section"); } string headingID = "h" + IncrementID; CreateAppendXmlAttribute(nccDocument, headingNode, "id", headingID); bodyNode.AppendChild(headingNode); // create smil document string smilNumericFrag = (sectionIndex + 1).ToString().PadLeft(3, '0'); string smilFileName = smilNumericFrag + ".smil"; XmlDocument smilDocument = CreateSmilStubDocument(); XmlNode smilBodyNode = smilDocument.GetElementsByTagName("body")[0]; // create main seq XmlNode mainSeq = smilDocument.CreateElement(null, "seq", smilBodyNode.NamespaceURI); CreateAppendXmlAttribute(smilDocument, mainSeq, "id", "sq" + IncrementID); // declare aseq node which is parent of audio elements XmlNode seqNode_AudioParent = null; // declare seq for heading phrase XmlNode seqNode_HeadingAudioParent = null; smilBodyNode.AppendChild(mainSeq); bool isFirstPhrase = true; EmptyNode adjustedPageNode = m_NextSectionPageAdjustmentDictionary[section]; bool isPreviousNodeEmptyPage = false; for (int i = 0; i < section.PhraseChildCount || adjustedPageNode != null; i++) { EmptyNode phrase = null; //first handle the first phrase of the project if it is also the page // in such a case i=0 will be skipped being page, second phrase is exported and then first page is inserted to i=2 if (i == 2 && m_FirstPageNumberedPhraseOfFirstSection != null) { phrase = m_FirstPageNumberedPhraseOfFirstSection; m_FirstPageNumberedPhraseOfFirstSection = null; --i; } else if (i < section.PhraseChildCount) { phrase = section.PhraseChild(i); } else { phrase = adjustedPageNode; adjustedPageNode = null; } if (phrase.Role_ == EmptyNode.Role.Page && isFirstPhrase && i < section.PhraseChildCount) { continue; } if ((phrase is PhraseNode && phrase.Used) || (phrase is EmptyNode && phrase.Role_ == EmptyNode.Role.Page && phrase.Used)) { string pageID = null; XmlNode pageNode = null; if (!isFirstPhrase && phrase.Role_ == EmptyNode.Role.Page) { string strClassVal = null; // increment page counts and get page kind switch (phrase.PageNumber.Kind) { case PageKind.Front: m_PageFrontCount++; strClassVal = "page-front"; break; case PageKind.Normal: m_PageNormalCount++; if (phrase.PageNumber.Number > m_MaxPageNormal) { m_MaxPageNormal = phrase.PageNumber.Number; } strClassVal = "page-normal"; break; case PageKind.Special: m_PageSpecialCount++; strClassVal = "page-special"; break; } pageNode = nccDocument.CreateElement(null, "span", bodyNode.NamespaceURI); CreateAppendXmlAttribute(nccDocument, pageNode, "class", strClassVal); pageID = "p" + IncrementID; CreateAppendXmlAttribute(nccDocument, pageNode, "id", pageID); bodyNode.AppendChild(pageNode); } // create smil nodes // if phrase node is first phrase of section or is page node then create par and text if (isFirstPhrase || phrase.Role_ == EmptyNode.Role.Page || isPreviousNodeEmptyPage) { // create par XmlNode parNode = smilDocument.CreateElement(null, "par", smilBodyNode.NamespaceURI); mainSeq.AppendChild(parNode); CreateAppendXmlAttribute(smilDocument, parNode, "endsync", "last"); CreateAppendXmlAttribute(smilDocument, parNode, "id", "pr" + IncrementID); XmlNode txtNode = smilDocument.CreateElement(null, "text", smilBodyNode.NamespaceURI); parNode.AppendChild(txtNode); string txtID = "txt" + IncrementID; CreateAppendXmlAttribute(smilDocument, txtNode, "id", txtID); if (isFirstPhrase || (isPreviousNodeEmptyPage && phrase.Role_ != EmptyNode.Role.Page)) { //if(phrase.PageNumber != null) Console.WriteLine("Page: " + phrase.PageNumber.ToString()); //Console.WriteLine("first page " + isFirstPhrase + " prev empty page " + isPreviousNodeEmptyPage); CreateAppendXmlAttribute(smilDocument, txtNode, "src", nccFileName + "#" + headingID); } else if (pageNode != null) { CreateAppendXmlAttribute(smilDocument, txtNode, "src", nccFileName + "#" + pageID); } // create seq which will hol audio children if (phrase is PhraseNode) { seqNode_AudioParent = smilDocument.CreateElement(null, "seq", smilBodyNode.NamespaceURI); parNode.AppendChild(seqNode_AudioParent); // hold seq for heading phrase in a variable. if (isFirstPhrase) { seqNode_HeadingAudioParent = seqNode_AudioParent; } CreateAppendXmlAttribute(smilDocument, seqNode_AudioParent, "id", "sq" + IncrementID); } // add anchor and href to ncc elements XmlNode anchorNode = nccDocument.CreateElement(null, "a", bodyNode.NamespaceURI); if (isFirstPhrase) { headingNode.AppendChild(anchorNode); CreateAppendXmlAttribute(nccDocument, anchorNode, "href", smilFileName + "#" + txtID); anchorNode.AppendChild( nccDocument.CreateTextNode(section.Label)); } else if (pageNode != null) { pageNode.AppendChild(anchorNode); CreateAppendXmlAttribute(nccDocument, anchorNode, "href", smilFileName + "#" + txtID); anchorNode.AppendChild( nccDocument.CreateTextNode(phrase.PageNumber.ToString())); } } // create audio elements for external audio medias if (phrase is PhraseNode) { Channel publishChannel = m_Presentation.ChannelsManager.GetChannelsByName(urakawa.daisy.export.Daisy3_Export.PUBLISH_AUDIO_CHANNEL_NAME)[0]; ExternalAudioMedia externalMedia = (ExternalAudioMedia)phrase.GetProperty <ChannelsProperty>().GetMedia(publishChannel); XmlNode audioNode = smilDocument.CreateElement(null, "audio", smilBodyNode.NamespaceURI); seqNode_AudioParent.AppendChild(audioNode); string relativeSRC = AddSectionNameToAudioFile? AddSectionNameToAudioFileName(externalMedia.Src, phrase.ParentAs <SectionNode>().Label): Path.GetFileName(externalMedia.Src); CreateAppendXmlAttribute(smilDocument, audioNode, "src", relativeSRC); CreateAppendXmlAttribute(smilDocument, audioNode, "clip-begin", GetNPTSmiltime(new TimeSpan(externalMedia.ClipBegin.AsTimeSpanTicks))); CreateAppendXmlAttribute(smilDocument, audioNode, "clip-end", GetNPTSmiltime(new TimeSpan(externalMedia.ClipEnd.AsTimeSpanTicks))); CreateAppendXmlAttribute(smilDocument, audioNode, "id", "aud" + IncrementID); sectionDuration.Add(externalMedia.Duration); if (!m_FilesList.Contains(relativeSRC)) { m_FilesList.Add(relativeSRC); } // copy audio element if phrase has heading role and is not first phrase if (phrase.Role_ == EmptyNode.Role.Heading && !isFirstPhrase) { XmlNode audioNodeCopy = audioNode.Clone(); audioNodeCopy.Attributes.GetNamedItem("id").Value = "aud" + IncrementID; seqNode_HeadingAudioParent.PrependChild(audioNodeCopy); sectionDuration.Add(externalMedia.Duration); } }//Check for audio containing phrase ends isFirstPhrase = false; if (phrase is EmptyNode && phrase.Role_ == EmptyNode.Role.Page) { isPreviousNodeEmptyPage = true; } else { isPreviousNodeEmptyPage = false; } } // if for phrasenode ends } // for loop ends // check if heading node have some children else remove it. // it is possible that all phrases are empty phrases or unused phrases, so there are no anchor children of heading node. if (headingNode.ChildNodes.Count == 0) { bodyNode.RemoveChild(headingNode); } else { // first increment exported section count m_ExportedSectionCount++; string strDurTime = TruncateTimeToDecimalPlaces(new TimeSpan(sectionDuration.AsTimeSpanTicks).TotalSeconds.ToString(System.Globalization.CultureInfo.CreateSpecificCulture("en-US")), 3); //string strDurTime = Math.Round ( sectionDuration.getTime ().TotalSeconds, 3, MidpointRounding.ToEven).ToString (); strDurTime = strDurTime + "s"; CreateAppendXmlAttribute(smilDocument, mainSeq, "dur", strDurTime); //AddSmilHeadElements ( smilDocument, m_SmilElapseTime.ToString (), sectionDuration.ToString () ); AddSmilHeadElements(smilDocument, AdjustTimeStringForDay(new TimeSpan(m_SmilElapseTime.AsTimeSpanTicks)), AdjustTimeStringForDay(new TimeSpan(sectionDuration.AsTimeSpanTicks))); m_SmilElapseTime.Add(sectionDuration); m_SmilFile_TitleMap.Add(smilFileName, section.Label); WriteXmlDocumentToFile(smilDocument, Path.Combine(m_ExportDirectory, smilFileName)); if (!m_FilesList.Contains(smilFileName)) { m_FilesList.Add(smilFileName); } } }
protected virtual void CreateDTBookDocument() { // check if there is preserved internal DTD //string[] dtbFilesList = Directory.GetFiles(m_Presentation.DataProviderManager.DataFileDirectoryFullPath, daisy.import.Daisy3_Import.INTERNAL_DTD_NAME, SearchOption.AllDirectories); //string strInternalDTD = null; //if (dtbFilesList.Length > 0) //{ // strInternalDTD = File.ReadAllText(dtbFilesList[0]); // if (strInternalDTD.Trim() == "") strInternalDTD = null; //} List <ExternalFileData> list_ExternalStyleSheets = new List <ExternalFileData>(); string strInternalDTD = null; foreach (ExternalFiles.ExternalFileData efd in m_Presentation.ExternalFilesDataManager.ManagedObjects.ContentsAs_Enumerable) { if (RequestCancellation) { return; } if (efd is ExternalFiles.DTDExternalFileData && efd.OriginalRelativePath == daisy.import.Daisy3_Import.INTERNAL_DTD_NAME && !efd.IsPreservedForOutputFile && string.IsNullOrEmpty(strInternalDTD)) { StreamReader sr = new StreamReader(efd.OpenInputStream(), Encoding.UTF8); strInternalDTD = sr.ReadToEnd(); } else if (efd is ExternalFiles.CSSExternalFileData || efd is XSLTExternalFileData //&& !efd.OriginalRelativePath.StartsWith(SupportedMetadata_Z39862005.MATHML_XSLT_METADATA) ) { list_ExternalStyleSheets.Add(efd); } } if (RequestCancellation) { return; } //m_ProgressPercentage = 0; reportProgress(-1, UrakawaSDK_daisy_Lang.CreatingXMLFile); XmlDocument DTBookDocument = XmlDocumentHelper.CreateStub_DTBDocument(m_Presentation.Language, strInternalDTD, list_ExternalStyleSheets); string mathML_XSLT = null; foreach (ExternalFileData efd in list_ExternalStyleSheets) { string filename = efd.OriginalRelativePath; if (filename.StartsWith(SupportedMetadata_Z39862005.MATHML_XSLT_METADATA)) { filename = filename.Substring(SupportedMetadata_Z39862005.MATHML_XSLT_METADATA.Length); mathML_XSLT = filename; } filename = FileDataProvider.EliminateForbiddenFileNameCharacters(filename); if (efd.IsPreservedForOutputFile && !m_FilesList_ExternalFiles.Contains(filename)) { string filePath = Path.Combine(m_OutputDirectory, filename); efd.DataProvider.ExportDataStreamToFile(filePath, true); m_FilesList_ExternalFiles.Add(filename); } } string mathPrefix = m_Presentation.RootNode.GetXmlNamespacePrefix(DiagramContentModelHelper.NS_URL_MATHML); if (!string.IsNullOrEmpty(mathPrefix) && string.IsNullOrEmpty(mathML_XSLT)) { string appDir = System.AppDomain.CurrentDomain.BaseDirectory; string xsltFileName = FileDataProvider.EliminateForbiddenFileNameCharacters(SupportedMetadata_Z39862005._builtInMathMLXSLT); string xsltFullPath = Path.Combine(appDir, xsltFileName); if (File.Exists(xsltFullPath)) { string destFile = Path.Combine(m_OutputDirectory, xsltFileName); File.Copy(xsltFullPath, destFile, true); try { File.SetAttributes(destFile, FileAttributes.Normal); } catch { } m_FilesList_ExternalFiles.Add(xsltFileName); } } m_ListOfLevels = new List <TreeNode>(); Dictionary <string, string> old_New_IDMap = new Dictionary <string, string>(); List <XmlAttribute> referencingAttributesList = new List <XmlAttribute>(); // add metadata XmlNode headNode = XmlDocumentHelper.GetFirstChildElementOrSelfWithName(DTBookDocument, true, "head", null); //DTBookDocument.GetElementsByTagName("head")[0] Metadata mdId = AddMetadata_DtbUid(false, DTBookDocument, headNode); AddMetadata_Generator(DTBookDocument, headNode); bool hasMathML_z39_86_extension_version = false; bool hasMathML_DTBook_XSLTFallback = false; // todo: filter-out unecessary metadata for DTBOOK (e.g. dtb:multimediatype) foreach (Metadata m in m_Presentation.Metadatas.ContentsAs_Enumerable) { if (mdId == m) { continue; } XmlNode metaNode = DTBookDocument.CreateElement(null, "meta", headNode.NamespaceURI); headNode.AppendChild(metaNode); string name = m.NameContentAttribute.Name; if (name == SupportedMetadata_Z39862005._z39_86_extension_version) { hasMathML_z39_86_extension_version = true; } else if (name == SupportedMetadata_Z39862005.MATHML_XSLT_METADATA) { hasMathML_DTBook_XSLTFallback = true; } string prefix; string localName; urakawa.property.xml.XmlProperty.SplitLocalName(name, out prefix, out localName); if (!string.IsNullOrEmpty(prefix)) { // split the metadata name and make first alphabet upper, required for daisy 3.0 localName = localName.Substring(0, 1).ToUpper() + localName.Remove(0, 1); name = prefix + ":" + localName; } XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, metaNode, "name", name); XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, metaNode, "content", m.NameContentAttribute.Value); // add metadata optional attributes if any foreach (MetadataAttribute ma in m.OtherAttributes.ContentsAs_Enumerable) { if (ma.Name == "id" || ma.Name == Metadata.PrimaryIdentifierMark) { continue; } XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, metaNode, ma.Name, ma.Value); } } if (!string.IsNullOrEmpty(mathML_XSLT)) { DebugFix.Assert(hasMathML_z39_86_extension_version); DebugFix.Assert(hasMathML_DTBook_XSLTFallback); } if (!string.IsNullOrEmpty(mathPrefix) && !hasMathML_z39_86_extension_version) { XmlNode metaNode = DTBookDocument.CreateElement(null, "meta", headNode.NamespaceURI); headNode.AppendChild(metaNode); XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, metaNode, "name", SupportedMetadata_Z39862005._z39_86_extension_version); XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, metaNode, "content", "1.0"); XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, metaNode, "scheme", DiagramContentModelHelper.NS_URL_MATHML); } if (!string.IsNullOrEmpty(mathPrefix) && !hasMathML_DTBook_XSLTFallback) { XmlNode metaNode = DTBookDocument.CreateElement(null, "meta", headNode.NamespaceURI); headNode.AppendChild(metaNode); XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, metaNode, "name", SupportedMetadata_Z39862005.MATHML_XSLT_METADATA); XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, metaNode, "content", string.IsNullOrEmpty(mathML_XSLT) ? SupportedMetadata_Z39862005._builtInMathMLXSLT : mathML_XSLT); XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, metaNode, "scheme", DiagramContentModelHelper.NS_URL_MATHML); } // add elements to book body m_TreeNode_XmlNodeMap = new Dictionary <TreeNode, XmlNode>(); XmlNode bookNode = XmlDocumentHelper.GetFirstChildElementOrSelfWithName(DTBookDocument, true, "book", null); //DTBookDocument.GetElementsByTagName("book")[0]; if (bookNode == null) { bookNode = XmlDocumentHelper.GetFirstChildElementOrSelfWithName(DTBookDocument, true, "body", null); } XmlNode docRootNode = XmlDocumentHelper.GetFirstChildElementOrSelfWithName(DTBookDocument, true, "dtbook", null); if (docRootNode == null) { docRootNode = XmlDocumentHelper.GetFirstChildElementOrSelfWithName(DTBookDocument, true, "html", null); } if (false && !string.IsNullOrEmpty(mathML_XSLT)) // namespace prefix attribute automatically added for each m:math element because of MathML DTD { XmlDocumentHelper.CreateAppendXmlAttribute( DTBookDocument, bookNode, XmlReaderWriterHelper.NS_PREFIX_XMLNS + ":" + "dtbook", bookNode.NamespaceURI, XmlReaderWriterHelper.NS_URL_XMLNS ); } m_ListOfLevels.Add(m_Presentation.RootNode); m_TreeNode_XmlNodeMap.Add(m_Presentation.RootNode, bookNode); XmlNode currentXmlNode = null; bool isHeadingNodeAvailable = true; m_Presentation.RootNode.AcceptDepthFirst( delegate(TreeNode n) { if (RequestCancellation) { return(false); } // add to list of levels if xml property has level string //QualifiedName qName = n.GetXmlElementQName(); //if (qName != null && // (qName.LocalName.StartsWith("level") || qName.LocalName == "doctitle" || qName.LocalName == "docauthor")) //{ // m_ListOfLevels.Add(n); //} if (doesTreeNodeTriggerNewSmil(n)) { if (!isHeadingNodeAvailable && m_ListOfLevels.Count > 1) { m_ListOfLevels.RemoveAt(m_ListOfLevels.Count - 1); //System.Windows.Forms.MessageBox.Show ( "removing :" + m_ListOfLevels.Count.ToString () ); } m_ListOfLevels.Add(n); isHeadingNodeAvailable = false; reportProgress(-1, UrakawaSDK_daisy_Lang.CreatingXMLFile); } if (IsHeadingNode(n)) { isHeadingNodeAvailable = true; } if (n.HasXmlProperty && (n.GetXmlElementLocalName() == "note" || n.GetXmlElementLocalName() == "annotation")) { m_NotesNodeList.Add(n); } property.xml.XmlProperty xmlProp = n.GetXmlProperty(); if (xmlProp == null) { string txtx = n.GetTextMedia() != null ? n.GetTextMedia().Text : null; if (txtx != null) { XmlNode textNode = DTBookDocument.CreateTextNode(txtx); ExternalAudioMedia extAudio = GetExternalAudioMedia(n); if (extAudio == null) { m_TreeNode_XmlNodeMap[n.Parent].AppendChild(textNode); m_TreeNode_XmlNodeMap.Add(n, textNode); } else { Debug.Fail("TreeNode without XmlProperty but with TextMedia cannot have Audio attached to it ! (reason: at authoring time, an XmlProperty should have been added when audio was recorded for the pure-text TreeNode) => " + txtx); //XmlNode textParent = DTBookDocument.CreateElement(null, "sent", bookNode.NamespaceURI); //textParent.AppendChild(textNode); //m_TreeNode_XmlNodeMap[n.Parent].AppendChild(textParent); //m_TreeNode_XmlNodeMap.Add(n, textParent); } } return(true); } // create sml node in dtbook document // code removed because XmlProperty stores proper namespaces, useful for inline MathML, SVG, whatever... //string name = xmlProp.LocalName; //string prefix = name.Contains(":") ? name.Split(':')[0] : null; //string elementName = name.Contains(":") ? name.Split(':')[1] : name; //currentXmlNode = DTBookDocument.CreateElement(prefix, elementName, bookNode.NamespaceURI); bool notBookRoot = !"book".Equals(xmlProp.LocalName, StringComparison.OrdinalIgnoreCase) && !"body".Equals(xmlProp.LocalName, StringComparison.OrdinalIgnoreCase); bool forceXmlNamespacePrefix = false; if ( //xmlProp.LocalName.Equals("math", StringComparison.OrdinalIgnoreCase) xmlProp.GetNamespaceUri() == DiagramContentModelHelper.NS_URL_MATHML && bookNode.LocalName.Equals("book", StringComparison.OrdinalIgnoreCase) ) { // Hack, because some MathML in DAISY is produced // with redundant (and DTD-invalid) xmlns="http://MATHML" forceXmlNamespacePrefix = true; } if (!notBookRoot) { currentXmlNode = bookNode; } else { XmlNode xmlNodeParent = m_TreeNode_XmlNodeMap[n.Parent]; string nsUri = n.GetXmlNamespaceUri(); if (string.IsNullOrEmpty(nsUri)) { nsUri = xmlNodeParent.NamespaceURI; } DebugFix.Assert(!string.IsNullOrEmpty(nsUri)); if (string.IsNullOrEmpty(nsUri)) { nsUri = bookNode.NamespaceURI; } if (string.IsNullOrEmpty(nsUri)) { nsUri = DTBookDocument.DocumentElement.NamespaceURI; } if (string.IsNullOrEmpty(nsUri)) { nsUri = DTBookDocument.NamespaceURI; } string prefix = (forceXmlNamespacePrefix || n.NeedsXmlNamespacePrefix()) ? n.GetXmlNamespacePrefix(nsUri) : null; currentXmlNode = DTBookDocument.CreateElement( prefix, xmlProp.LocalName, nsUri); xmlNodeParent.AppendChild(currentXmlNode); m_TreeNode_XmlNodeMap.Add(n, currentXmlNode); } // add attributes for (int i = 0; i < xmlProp.Attributes.Count; i++) { property.xml.XmlAttribute xmlAttr = xmlProp.Attributes.Get(i); string prefix = xmlAttr.Prefix; string nameWithoutPrefix = xmlAttr.PrefixedLocalName != null ? xmlAttr.PrefixedLocalName : xmlAttr.LocalName; if (!string.IsNullOrEmpty(prefix)) { string nsUriPrefix = xmlProp.GetNamespaceUri(prefix); if (string.IsNullOrEmpty(nsUriPrefix)) { #if DEBUG Debugger.Break(); #endif //DEBUG nsUriPrefix = currentXmlNode.GetNamespaceOfPrefix(prefix); } if (!string.IsNullOrEmpty(nsUriPrefix) && string.IsNullOrEmpty(DTBookDocument.DocumentElement.GetNamespaceOfPrefix(prefix)) && string.IsNullOrEmpty(bookNode.GetNamespaceOfPrefix(prefix))) { XmlDocumentHelper.CreateAppendXmlAttribute( DTBookDocument, docRootNode, //bookNode, XmlReaderWriterHelper.NS_PREFIX_XMLNS + ":" + prefix, nsUriPrefix, XmlReaderWriterHelper.NS_URL_XMLNS ); } } //todo: check ID attribute, normalize with fresh new list of IDs // (warning: be careful maintaining ID REFS, such as idref attributes for annotation/annoref and prodnote/noteref // (be careful because idref contain URIs with hash character), // and also the special imgref and headers attributes which contain space-separated list of IDs, not URIs) if (nameWithoutPrefix == "id") // xmlAttr.LocalName == "id" || xmlAttr.LocalName == XmlReaderWriterHelper.XmlId) { string id_New = GetNextID(ID_DTBPrefix); XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, currentXmlNode, "id", id_New); if (!old_New_IDMap.ContainsKey(xmlAttr.Value)) { old_New_IDMap.Add(xmlAttr.Value, id_New); } else { System.Diagnostics.Debug.Fail("Duplicate ID found in original DTBook document", "Original DTBook document has duplicate ID: " + xmlProp.Attributes.Get(i).Value); } } else { XmlNode xmlNd = null; if (currentXmlNode == bookNode && (prefix == XmlReaderWriterHelper.NS_PREFIX_XMLNS || nameWithoutPrefix == "lang")) { // Hack: to make sure DTD validation passes. xmlNd = docRootNode; } else { xmlNd = currentXmlNode; } if (forceXmlNamespacePrefix && nameWithoutPrefix == XmlReaderWriterHelper.NS_PREFIX_XMLNS && xmlAttr.Value == DiagramContentModelHelper.NS_URL_MATHML ) { bool debug = true; // skip xmlns="http://MATH" } else { XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, xmlNd, xmlAttr.LocalName, xmlAttr.Value, xmlAttr.GetNamespaceUri()); } } } // for loop ends if (!notBookRoot) { return(true); } if (xmlProp.LocalName == "imggroup") { m_TempImageId = new List <string>(1); } if (m_TempImageId != null && // !string.IsNullOrEmpty(m_TempImageId) (xmlProp.LocalName == "caption" || xmlProp.LocalName == "prodnote")) { string imgIds = ""; foreach (string imgId in m_TempImageId) { imgIds += imgId + " "; } imgIds = imgIds.Trim(); if (!string.IsNullOrEmpty(imgIds)) { XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, currentXmlNode, "imgref", imgIds); } } XmlAttributeCollection currentXmlNodeAttrs = currentXmlNode.Attributes; // add id attribute in case it do not exists and it is required if (IsIDRequired(currentXmlNode.LocalName) && currentXmlNodeAttrs != null) { XmlNode idAttr = currentXmlNodeAttrs.GetNamedItem("id"); if (idAttr == null) { string id = GetNextID(ID_DTBPrefix); XmlDocumentHelper.CreateAppendXmlAttribute(DTBookDocument, currentXmlNode, "id", id); } else if (xmlProp.LocalName != null && xmlProp.LocalName.Equals("img", StringComparison.OrdinalIgnoreCase) && m_TempImageId != null) { string id = idAttr.Value; m_TempImageId.Add(id); } } // add text from text property string txt = n.GetTextMedia() != null ? n.GetTextMedia().Text : null; if (txt != null) { XmlNode textNode = DTBookDocument.CreateTextNode(txt); currentXmlNode.AppendChild(textNode); DebugFix.Assert(n.Children.Count == 0); } // if current xmlnode is referencing node, add its referencing attribute to referencingAttributesList AddReferencingNodeToReferencedAttributesList(currentXmlNode, referencingAttributesList); if (currentXmlNodeAttrs != null && currentXmlNode.LocalName != null) { bool isHTML = @"body".Equals(m_Presentation.RootNode.GetXmlElementLocalName(), StringComparison.OrdinalIgnoreCase); //n.Presentation // TODO: special treatment of subfolders in file paths (restore full hierarchy, including OPF, XHTMLs, etc., not just referenced media assets) if (currentXmlNode.LocalName.Equals("img", StringComparison.OrdinalIgnoreCase)) { XmlAttribute imgSrcAttribute = (XmlAttribute)currentXmlNodeAttrs.GetNamedItem("src"); if (imgSrcAttribute != null && n.GetImageMedia() != null && n.GetImageMedia() is media.data.image.ManagedImageMedia) { media.data.image.ManagedImageMedia managedImage = (media.data.image.ManagedImageMedia)n.GetImageMedia(); //if (FileDataProvider.isHTTPFile(managedImage.ImageMediaData.OriginalRelativePath)) //exportImageName = Path.GetFileName(managedImage.ImageMediaData.OriginalRelativePath); string exportImageName = //Path.GetFileName FileDataProvider.EliminateForbiddenFileNameCharacters (managedImage.ImageMediaData.OriginalRelativePath) ; string destPath = Path.Combine(m_OutputDirectory, exportImageName); if (!File.Exists(destPath)) { if (RequestCancellation) { return(false); } managedImage.ImageMediaData.DataProvider.ExportDataStreamToFile(destPath, false); } imgSrcAttribute.Value = FileDataProvider.UriEncode(exportImageName); if (!m_FilesList_Image.Contains(exportImageName)) { m_FilesList_Image.Add(exportImageName); } generateImageDescriptionInDTBook(n, currentXmlNode, exportImageName, DTBookDocument); } } else if (currentXmlNode.LocalName.Equals(DiagramContentModelHelper.Math, StringComparison.OrdinalIgnoreCase)) { XmlAttribute imgSrcAttribute = (XmlAttribute)currentXmlNodeAttrs.GetNamedItem("altimg"); if (imgSrcAttribute != null && n.GetImageMedia() != null && n.GetImageMedia() is media.data.image.ManagedImageMedia) { media.data.image.ManagedImageMedia managedImage = (media.data.image.ManagedImageMedia)n.GetImageMedia(); //if (FileDataProvider.isHTTPFile(managedImage.ImageMediaData.OriginalRelativePath)) //exportImageName = Path.GetFileName(managedImage.ImageMediaData.OriginalRelativePath); string exportImageName = //Path.GetFileName FileDataProvider.EliminateForbiddenFileNameCharacters (managedImage.ImageMediaData.OriginalRelativePath) ; string destPath = Path.Combine(m_OutputDirectory, exportImageName); if (!File.Exists(destPath)) { if (RequestCancellation) { return(false); } managedImage.ImageMediaData.DataProvider.ExportDataStreamToFile(destPath, false); } imgSrcAttribute.Value = FileDataProvider.UriEncode(exportImageName); if (!m_FilesList_Image.Contains(exportImageName)) { m_FilesList_Image.Add(exportImageName); } } } #if SUPPORT_AUDIO_VIDEO else if (currentXmlNode.LocalName.Equals("video", StringComparison.OrdinalIgnoreCase) || ( currentXmlNode.LocalName.Equals("source", StringComparison.OrdinalIgnoreCase) && currentXmlNode.ParentNode != null && currentXmlNode.ParentNode.LocalName.Equals("video", StringComparison.OrdinalIgnoreCase) ) ) { XmlAttribute videoSrcAttribute = (XmlAttribute)currentXmlNodeAttrs.GetNamedItem("src"); if (videoSrcAttribute != null && n.GetVideoMedia() != null && n.GetVideoMedia() is ManagedVideoMedia) { ManagedVideoMedia managedVideo = (ManagedVideoMedia)n.GetVideoMedia(); //if (FileDataProvider.isHTTPFile(managedVideo.VideoMediaData.OriginalRelativePath)) //exportVideoName = Path.GetFileName(managedVideo.VideoMediaData.OriginalRelativePath); string exportVideoName = FileDataProvider.EliminateForbiddenFileNameCharacters( managedVideo.VideoMediaData.OriginalRelativePath); string destPath = Path.Combine(m_OutputDirectory, exportVideoName); if (!File.Exists(destPath)) { if (RequestCancellation) { return(false); } managedVideo.VideoMediaData.DataProvider.ExportDataStreamToFile(destPath, false); } videoSrcAttribute.Value = FileDataProvider.UriEncode(exportVideoName); if (!m_FilesList_Video.Contains(exportVideoName)) { m_FilesList_Video.Add(exportVideoName); } } } else if (currentXmlNode.LocalName.Equals("audio", StringComparison.OrdinalIgnoreCase) || ( currentXmlNode.LocalName.Equals("source", StringComparison.OrdinalIgnoreCase) && currentXmlNode.ParentNode != null && currentXmlNode.ParentNode.LocalName.Equals("audio", StringComparison.OrdinalIgnoreCase) ) ) { XmlAttribute audioSrcAttribute = (XmlAttribute)currentXmlNodeAttrs.GetNamedItem("src"); ManagedAudioMedia managedAudio = n.GetManagedAudioMedia(); if (audioSrcAttribute != null && managedAudio != null) { //if (FileDataProvider.isHTTPFile(managedAudio.AudioMediaData.OriginalRelativePath)) //exportAudioName = Path.GetFileName(managedAudio.AudioMediaData.OriginalRelativePath); string exportAudioName = FileDataProvider.EliminateForbiddenFileNameCharacters( managedAudio.AudioMediaData.OriginalRelativePath); string destPath = Path.Combine(m_OutputDirectory, exportAudioName); if (!File.Exists(destPath)) { if (RequestCancellation) { return(false); } managedAudio.AudioMediaData.DataProvider.ExportDataStreamToFile(destPath, false); } audioSrcAttribute.Value = FileDataProvider.UriEncode(exportAudioName); if (!m_FilesList_Audio.Contains(exportAudioName)) { m_FilesList_Audio.Add(exportAudioName); } } } #endif } return(true); }, delegate(urakawa.core.TreeNode n) { property.xml.XmlProperty xmlProp = n.GetXmlProperty(); //QualifiedName qName = n.GetXmlElementQName(); if (xmlProp != null && xmlProp.LocalName == "imggroup") { m_TempImageId = null; } }); if (RequestCancellation) { return; } // set references to new ids foreach (XmlAttribute attr in referencingAttributesList) { string strIDToFind = attr.Value; if (strIDToFind.IndexOf('#') >= 0) //strIDToFind.Contains("#") { strIDToFind = strIDToFind.Split('#')[1]; } string str; old_New_IDMap.TryGetValue(strIDToFind, out str); if (!string.IsNullOrEmpty(str)) //old_New_IDMap.ContainsKey(strIDToFind)) { string id_New = str; // old_New_IDMap[strIDToFind]; attr.Value = "#" + id_New; } } m_DTBDocument = DTBookDocument; //CommonFunctions.WriteXmlDocumentToFile(DTBookDocument, // Path.Combine(m_OutputDirectory, m_Filename_Content)); }
private void CreateAudioFileForAlternateContentProperty() { if (m_AlternateContentPropertiesList == null || m_AlternateContentPropertiesList.Count == 0) { return; } foreach (AlternateContentProperty altProperty in m_AlternateContentPropertiesList) { foreach (AlternateContent ac in altProperty.AlternateContents.ContentsAs_Enumerable) { if (ac.Audio != null) { Stream audioPcmStream = null; if (ac.Audio.AudioMediaData != null) { audioPcmStream = ac.Audio.AudioMediaData.OpenPcmInputStream(); } else { Debug.Fail("This should never happen !!"); return; } long bytesBegin = m_TransientWavFileStream.Position - (long)m_TransientWavFileStreamRiffOffset; try { const uint BUFFER_SIZE = 1024 * 1024 * 3; // 3 MB MAX BUFFER uint streamCount = StreamUtils.Copy(audioPcmStream, 0, m_TransientWavFileStream, BUFFER_SIZE); } catch { m_TransientWavFileStream.Close(); m_TransientWavFileStream = null; m_TransientWavFileStreamRiffOffset = 0; #if DEBUG Debugger.Break(); #endif } finally { audioPcmStream.Close(); } long bytesEnd = m_TransientWavFileStream.Position - (long)m_TransientWavFileStreamRiffOffset; string src = m_RootNode.Presentation.RootUri.MakeRelativeUri(GetCurrentAudioFileUri()).ToString(); ExternalAudioMedia extAudioMedia = m_RootNode.Presentation.MediaFactory.Create <ExternalAudioMedia>(); extAudioMedia.Language = m_RootNode.Presentation.Language; extAudioMedia.Src = src; long timeBegin = m_RootNode.Presentation.MediaDataManager.DefaultPCMFormat.Data.ConvertBytesToTime(bytesBegin); long timeEnd = m_RootNode.Presentation.MediaDataManager.DefaultPCMFormat.Data.ConvertBytesToTime(bytesEnd); extAudioMedia.ClipBegin = new Time(timeBegin); extAudioMedia.ClipEnd = new Time(timeEnd); ac.ExternalAudio = extAudioMedia; // } } } }
protected void addAudio(TreeNode treeNode, XmlNode xmlNode, bool isSequence, string fullSmilPath) { if (RequestCancellation) { return; } string dirPath = Path.GetDirectoryName(fullSmilPath); XmlAttributeCollection audioAttrs = xmlNode.Attributes; if (audioAttrs == null || audioAttrs.Count == 0) { return; } XmlNode audioAttrSrc = audioAttrs.GetNamedItem("src"); if (audioAttrSrc == null || String.IsNullOrEmpty(audioAttrSrc.Value)) { return; } string src = FileDataProvider.UriDecode(audioAttrSrc.Value); XmlNode audioAttrClipBegin = audioAttrs.GetNamedItem("clipBegin"); XmlNode audioAttrClipEnd = audioAttrs.GetNamedItem("clipEnd"); Presentation presentation = treeNode.Presentation; // m_Project.Presentations.Get(0); ManagedAudioMedia media = null; string fullPath = Path.Combine(dirPath, src); fullPath = FileDataProvider.NormaliseFullFilePath(fullPath).Replace('/', '\\'); addOPF_GlobalAssetPath(fullPath); string ext = Path.GetExtension(src); if (ext.Equals(DataProviderFactory.AUDIO_WAV_EXTENSION, StringComparison.OrdinalIgnoreCase)) { FileDataProvider dataProv = null; if (!File.Exists(fullPath)) { Debug.Fail("File not found: " + fullPath); media = null; } else { //bool deleteSrcAfterCompletion = false; string fullWavPath = fullPath; FileDataProvider obj; m_OriginalAudioFile_FileDataProviderMap.TryGetValue(fullWavPath, out obj); if (obj != null) //m_OriginalAudioFile_FileDataProviderMap.ContainsKey(fullWavPath)) { if (m_AudioConversionSession.FirstDiscoveredPCMFormat == null) { DebugFix.Assert(obj.Presentation != presentation); Object appData = obj.AppData; DebugFix.Assert(appData != null); if (appData != null && appData is WavClip.PcmFormatAndTime) { m_AudioConversionSession.FirstDiscoveredPCMFormat = new AudioLibPCMFormat(); m_AudioConversionSession.FirstDiscoveredPCMFormat.CopyFrom(((WavClip.PcmFormatAndTime)appData).mFormat); } } if (obj.Presentation != presentation) { dataProv = (FileDataProvider)presentation.DataProviderFactory.Create(DataProviderFactory.AUDIO_WAV_MIME_TYPE); reportProgress(-1, String.Format(UrakawaSDK_daisy_Lang.CopyingAudio, Path.GetFileName(obj.DataFileFullPath))); dataProv.InitByCopyingExistingFile(obj.DataFileFullPath); //m_AudioConversionSession.RelocateDestinationFilePath(newfullWavPath, dataProv.DataFileFullPath); m_OriginalAudioFile_FileDataProviderMap.Remove(fullWavPath); m_OriginalAudioFile_FileDataProviderMap.Add(fullWavPath, dataProv); Object appData = obj.AppData; DebugFix.Assert(appData != null); if (appData != null && appData is WavClip.PcmFormatAndTime) { dataProv.AppData = new WavClip.PcmFormatAndTime(((WavClip.PcmFormatAndTime)appData).mFormat, ((WavClip.PcmFormatAndTime)appData).mTime); } } else { dataProv = obj; // m_OriginalAudioFile_FileDataProviderMap[fullWavPath]; } } else // create FileDataProvider { Stream wavStream = null; try { wavStream = File.Open(fullWavPath, FileMode.Open, FileAccess.Read, FileShare.Read); uint dataLength; AudioLibPCMFormat pcmInfo = null; pcmInfo = AudioLibPCMFormat.RiffHeaderParse(wavStream, out dataLength); if (m_AudioConversionSession.FirstDiscoveredPCMFormat == null) { //m_AudioConversionSession.FirstDiscoveredPCMFormat = new PCMFormatInfo(pcmInfo); m_AudioConversionSession.FirstDiscoveredPCMFormat = new AudioLibPCMFormat(); m_AudioConversionSession.FirstDiscoveredPCMFormat.CopyFrom(pcmInfo); } if (RequestCancellation) { return; } //if (m_firstTimePCMFormat) //{ // presentation.MediaDataManager.DefaultPCMFormat = new PCMFormatInfo(pcmInfo); // m_firstTimePCMFormat = false; //} if (!presentation.MediaDataManager.DefaultPCMFormat.Data.IsCompatibleWith(pcmInfo)) { wavStream.Close(); wavStream = null; reportProgress(-1, String.Format(UrakawaSDK_daisy_Lang.ConvertingAudio, Path.GetFileName(fullWavPath))); string newfullWavPath = m_AudioConversionSession.ConvertAudioFileFormat(fullWavPath); if (RequestCancellation) { return; } dataProv = (FileDataProvider)presentation.DataProviderFactory.Create(DataProviderFactory.AUDIO_WAV_MIME_TYPE); //Console.WriteLine("Source audio file to SDK audio file map (before creating SDK audio file): " + Path.GetFileName(fullWavPath) + " = " + dataProv.DataFileRelativePath); dataProv.InitByMovingExistingFile(newfullWavPath); m_AudioConversionSession.RelocateDestinationFilePath(newfullWavPath, dataProv.DataFileFullPath); m_OriginalAudioFile_FileDataProviderMap.Add(fullWavPath, dataProv); if (RequestCancellation) { return; } } else // use original wav file by copying it to data directory { dataProv = (FileDataProvider)presentation.DataProviderFactory.Create(DataProviderFactory.AUDIO_WAV_MIME_TYPE); //Console.WriteLine("Source audio file to SDK audio file map (before creating SDK audio file): " + Path.GetFileName(fullWavPath) + " = " + dataProv.DataFileRelativePath); reportProgress(-1, String.Format(UrakawaSDK_daisy_Lang.CopyingAudio, Path.GetFileName(fullWavPath))); dataProv.InitByCopyingExistingFile(fullWavPath); m_OriginalAudioFile_FileDataProviderMap.Add(fullWavPath, dataProv); if (RequestCancellation) { return; } } } finally { if (wavStream != null) { wavStream.Close(); } } } } // FileDataProvider key check ends if (RequestCancellation) { return; } media = addAudioWav(dataProv, audioAttrClipBegin, audioAttrClipEnd, treeNode); //media = addAudioWav ( fullWavPath, deleteSrcAfterCompletion, audioAttrClipBegin, audioAttrClipEnd ); } else if (ext.Equals(DataProviderFactory.AUDIO_MP3_EXTENSION, StringComparison.OrdinalIgnoreCase) || ext.Equals(DataProviderFactory.AUDIO_MP4_EXTENSION, StringComparison.OrdinalIgnoreCase) || ext.Equals(DataProviderFactory.AUDIO_MP4_EXTENSION_, StringComparison.OrdinalIgnoreCase)) { if (!File.Exists(fullPath)) { Debug.Fail("File not found: {0}", fullPath); return; } if (RequestCancellation) { return; } reportProgress(-1, String.Format(UrakawaSDK_daisy_Lang.DecodingAudio, Path.GetFileName(fullPath))); if (RequestCancellation) { return; } string fullMp34PathOriginal = fullPath; FileDataProvider obj; m_OriginalAudioFile_FileDataProviderMap.TryGetValue(fullMp34PathOriginal, out obj); FileDataProvider dataProv = null; if (obj != null) //m_OriginalAudioFile_FileDataProviderMap.ContainsKey(fullMp3PathOriginal)) { if (m_AudioConversionSession.FirstDiscoveredPCMFormat == null) { DebugFix.Assert(obj.Presentation != presentation); Object appData = obj.AppData; DebugFix.Assert(appData != null); if (appData != null && appData is WavClip.PcmFormatAndTime) { m_AudioConversionSession.FirstDiscoveredPCMFormat = new AudioLibPCMFormat(); m_AudioConversionSession.FirstDiscoveredPCMFormat.CopyFrom(((WavClip.PcmFormatAndTime)appData).mFormat); } } if (obj.Presentation != presentation) { dataProv = (FileDataProvider)presentation.DataProviderFactory.Create(DataProviderFactory.AUDIO_WAV_MIME_TYPE); reportProgress(-1, String.Format(UrakawaSDK_daisy_Lang.CopyingAudio, Path.GetFileName(obj.DataFileFullPath))); dataProv.InitByCopyingExistingFile(obj.DataFileFullPath); //m_AudioConversionSession.RelocateDestinationFilePath(newfullWavPath, dataProv.DataFileFullPath); m_OriginalAudioFile_FileDataProviderMap.Remove(fullMp34PathOriginal); m_OriginalAudioFile_FileDataProviderMap.Add(fullMp34PathOriginal, dataProv); Object appData = obj.AppData; DebugFix.Assert(appData != null); if (appData != null && appData is WavClip.PcmFormatAndTime) { dataProv.AppData = new WavClip.PcmFormatAndTime(((WavClip.PcmFormatAndTime)appData).mFormat, ((WavClip.PcmFormatAndTime)appData).mTime); } } else { dataProv = obj; // m_OriginalAudioFile_FileDataProviderMap[fullMp3PathOriginal]; } } else { string newfullWavPath = m_AudioConversionSession.ConvertAudioFileFormat(fullMp34PathOriginal); dataProv = (FileDataProvider)presentation.DataProviderFactory.Create(DataProviderFactory.AUDIO_WAV_MIME_TYPE); //Console.WriteLine("Source audio file to SDK audio file map (before creating SDK audio file): " + Path.GetFileName(fullMp34PathOriginal) + " = " + dataProv.DataFileRelativePath); dataProv.InitByMovingExistingFile(newfullWavPath); m_AudioConversionSession.RelocateDestinationFilePath(newfullWavPath, dataProv.DataFileFullPath); m_OriginalAudioFile_FileDataProviderMap.Add(fullMp34PathOriginal, dataProv); if (RequestCancellation) { return; } } if (dataProv != null) { //if (m_firstTimePCMFormat) //{ // Stream wavStream = null; // try // { // wavStream = File.Open(newfullWavPath, FileMode.Open, FileAccess.Read, FileShare.Read); // uint dataLength; // AudioLibPCMFormat pcmInfo = null; // pcmInfo = AudioLibPCMFormat.RiffHeaderParse(wavStream, out dataLength); // presentation.MediaDataManager.DefaultPCMFormat = new PCMFormatInfo(pcmInfo); // } // finally // { // if (wavStream != null) wavStream.Close(); // m_firstTimePCMFormat = false; // } //} if (RequestCancellation) { return; } //media = addAudioWav(newfullWavPath, true, audioAttrClipBegin, audioAttrClipEnd); media = addAudioWav(dataProv, audioAttrClipBegin, audioAttrClipEnd, treeNode); if (RequestCancellation) { return; } if (media == null) { #if DEBUG Debugger.Break(); #endif } } //} } if (RequestCancellation) { return; } if (media == null) { if (!TreenodesWithoutManagedAudioMediaData.Contains(treeNode)) { TreenodesWithoutManagedAudioMediaData.Add(treeNode); } Debug.Fail("Creating ExternalAudioMedia ??"); Time timeClipBegin = null; ExternalAudioMedia exmedia = presentation.MediaFactory.CreateExternalAudioMedia(); exmedia.Src = src; if (audioAttrClipBegin != null && !string.IsNullOrEmpty(audioAttrClipBegin.Value)) { timeClipBegin = new Time(); try { timeClipBegin = new Time(audioAttrClipBegin.Value); } catch (Exception ex) { string str = "CLIP BEGIN TIME PARSE FAIL: " + audioAttrClipBegin.Value; Console.WriteLine(str); Debug.Fail(str); } exmedia.ClipBegin = timeClipBegin; } if (audioAttrClipEnd != null && !string.IsNullOrEmpty(audioAttrClipEnd.Value)) { Time timeClipEnd = null; try { timeClipEnd = new Time(audioAttrClipEnd.Value); } catch (Exception ex) { string str = "CLIP END TIME PARSE FAIL: " + audioAttrClipEnd.Value; Console.WriteLine(str); Debug.Fail(str); } if (timeClipEnd != null) { try { exmedia.ClipEnd = timeClipEnd; } catch (Exception ex) { string str = "CLIP TIME ERROR (end < begin): " + timeClipBegin + " (" + (audioAttrClipBegin != null ? audioAttrClipBegin.Value : "N/A") + ") / " + timeClipEnd + " (" + audioAttrClipEnd.Value + ")"; Console.WriteLine(str); //Debug.Fail(str); } } } } if (RequestCancellation) { return; } if (media != null) { ChannelsProperty chProp = treeNode.GetChannelsProperty(); if (chProp == null) { chProp = presentation.PropertyFactory.CreateChannelsProperty(); treeNode.AddProperty(chProp); } if (isSequence) { #if ENABLE_SEQ_MEDIA SequenceMedia mediaSeq = chProp.GetMedia(m_audioChannel) as SequenceMedia; if (mediaSeq == null) { mediaSeq = presentation.MediaFactory.CreateSequenceMedia(); mediaSeq.AllowMultipleTypes = false; chProp.SetMedia(m_audioChannel, mediaSeq); } mediaSeq.ChildMedias.Insert(mediaSeq.ChildMedias.Count, media); #else ManagedAudioMedia existingMedia = chProp.GetMedia(presentation.ChannelsManager.GetOrCreateAudioChannel()) as ManagedAudioMedia; if (existingMedia == null) { chProp.SetMedia(presentation.ChannelsManager.GetOrCreateAudioChannel(), media); } else { // WARNING: WavAudioMediaData implementation differs from AudioMediaData: // the latter is naive and performs a stream binary copy, the latter is optimized and re-uses existing WavClips. // WARNING 2: The audio data from the given parameter gets emptied ! existingMedia.AudioMediaData.MergeWith(media.AudioMediaData); //Stream stream = seqManMedia.AudioMediaData.OpenPcmInputStream(); //try //{ // mediaData.AppendPcmData(stream, null); //} //finally //{ // stream.Close(); //} } #endif //ENABLE_SEQ_MEDIA } else { //#if DEBUG // ((WavAudioMediaData) media.AudioMediaData).checkWavClips(); //#endif //DEBUG chProp.SetMedia(presentation.ChannelsManager.GetOrCreateAudioChannel(), media); } } else { Debug.Fail("Media could not be created !"); } }
private static void CheckPublishedFiles(TreeNode node, Channel sourceCh, Channel destCh, Uri curWavUri_, MemoryStream curAudioData, PCMFormatInfo curPCMFormat) { Uri curWavUri = (curWavUri_ == null ? null : new Uri(curWavUri_.ToString())); if (node.HasProperties(typeof(ChannelsProperty))) { ChannelsProperty chProp = node.GetProperty <ChannelsProperty>(); ManagedAudioMedia mam = chProp.GetMedia(sourceCh) as ManagedAudioMedia; ExternalAudioMedia eam = chProp.GetMedia(destCh) as ExternalAudioMedia; Assert.AreEqual(mam == null, eam == null, "There may be external audio media if and only if there is managed audio media"); if (mam != null && eam != null) { Assert.IsTrue(mam.Duration.IsEqualTo(eam.Duration), "Duration of managed and external audio media differs"); if (eam.Uri != null) { FileStream wavFS_ = new FileStream(eam.Uri.LocalPath, FileMode.Open, FileAccess.Read, FileShare.None); Stream manAudioStream = mam.AudioMediaData.OpenPcmInputStream(); try { uint dataLength; AudioLibPCMFormat pcmInfo = AudioLibPCMFormat.RiffHeaderParse(wavFS_, out dataLength); Assert.IsTrue(pcmInfo.IsCompatibleWith(mam.AudioMediaData.PCMFormat.Data), "External audio has incompatible pcm format"); wavFS_.Position += pcmInfo.ConvertTimeToBytes(eam.ClipBegin.TimeAsMillisecondFloat); Assert.IsTrue( AudioLibPCMFormat.CompareStreamData(manAudioStream, wavFS_, (int)manAudioStream.Length), "External audio contains wrong data"); } finally { wavFS_.Close(); manAudioStream.Close(); } } if (curWavUri != null) { FileStream wavFS = new FileStream(curWavUri.LocalPath, FileMode.Open, FileAccess.Read, FileShare.None); try { uint dataLength; AudioLibPCMFormat pcmInfo = AudioLibPCMFormat.RiffHeaderParse(wavFS, out dataLength); Assert.IsTrue(pcmInfo.IsCompatibleWith(curPCMFormat.Data), "External audio has incompatible pcm format"); curAudioData.Position = 0; Assert.AreEqual(curAudioData.Length, (long)dataLength, "External audio has unexpected length"); Assert.IsTrue( AudioLibPCMFormat.CompareStreamData(curAudioData, wavFS, (int)curAudioData.Length), "External audio contains wrong data"); } finally { wavFS.Close(); } } if (curWavUri == null) { curWavUri = new Uri(eam.Uri.ToString()); curAudioData = new MemoryStream(); curPCMFormat = mam.AudioMediaData.PCMFormat; } else if (curWavUri.ToString() != eam.Uri.ToString()) { curWavUri = new Uri(eam.Uri.ToString()); curAudioData = new MemoryStream(); curPCMFormat = mam.AudioMediaData.PCMFormat; } Assert.IsTrue(curPCMFormat.ValueEquals(mam.AudioMediaData.PCMFormat), "Managed audio has incompatible pcm format"); Stream manAudio = mam.AudioMediaData.OpenPcmInputStream(); try { media.data.StreamUtils.CopyData(manAudio, curAudioData); } finally { manAudio.Close(); } } } foreach (TreeNode child in node.Children.ContentsAs_YieldEnumerable) { CheckPublishedFiles(child, sourceCh, destCh, curWavUri, curAudioData, curPCMFormat); } }