/// <summary> /// Opens and reads the data for the specified file. /// </summary> /// <param name="fileName">The full path and file name of the MP4 file to open.</param> /// <returns>An <see cref="Mp4File"/> object you can use to manipulate file.</returns> /// <exception cref="ArgumentException"> /// Thrown if the specified file name is <see langword="null"/> or the empty string. /// </exception> public static Mp4File Open(string fileName) { var file = new Mp4File(fileName); file.Load(); return(file); }
/// <inheritdoc/> public Video ReadVideo(string path) { var file = Mp4File.Open(path); var tags = file.Tags; if (tags is null) { throw new ArgumentException(default, nameof(path));
/// <summary> /// Read Mfra box. /// </summary> /// <param name="stream">Mp4 stream.</param> /// <returns>Mfra box.</returns> private Mp4MfraBox GetMfra(Mp4Stream stream) { stream.Position = stream.Length - 4; uint mfraSize = stream.ReadUInt32(); stream.Position = stream.Length - mfraSize; var file = new Mp4File(stream); return((Mp4MfraBox)file.Boxes[0]); }
public void ShowFile(Mp4File file) { RemoveViews(); if (file != null) { IMainView view = _Container.Resolve <IMainView>(); view.File = file; IRegion mainRegion = _RegionManager.Regions[RegionNames.MainRegion]; mainRegion.Add(view); mainRegion.Activate(view); } }
private void Open(object obj) { try { var openFileDialog = new OpenFileDialog { Filter = "MP4 Files (*.mp4,*.m4a,*.ismv,*.mov)|*.mp4;*.m4a;*.ismv;*.mov|All Files (*.*)|*.*", FilterIndex = 1 }; if (openFileDialog.ShowDialog() == true) { _Stream?.Close(); var backgroundWorker = new BackgroundWorker(); Exception exceptionError = null; backgroundWorker.DoWork += (object s, DoWorkEventArgs args) => { try { _Stream = new Mp4Stream(openFileDialog.OpenFile()); _File = new Mp4File(_Stream); List <Mp4Box> unknowBoxes = _File.Boxes.FindAll(b => b is Mp4UnknownBox); if (unknowBoxes.Count > 1) { throw new Exception("Too many unknown boxes."); } View.Dispatcher.Invoke(new Action(() => { View.RootNode = BuildTree(_File, Path.GetFileName(openFileDialog.FileName)); _Controller.RemoveViews(); })); } catch (Exception ex) { exceptionError = ex; } }; var progressWindow = new ProgressWindow(backgroundWorker); progressWindow.ShowDialog(); if (exceptionError != null) { throw exceptionError; } } } catch { MessageBox.Show("Error loading mp4 file", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary> /// /// </summary> /// <param name="file"></param> /// <param name="name"></param> /// <returns></returns> private TreeViewItem BuildTree(Mp4File file, string name) { ImageTreeViewItem root = new ImageTreeViewItem() { Text = name, ImageSource = "/Mp4Explorer;component/Images/movie_16.ico" }; foreach (Mp4Box box in file.Boxes) { root.Items.Add(new Mp4TreeNode(box)); } return(root); }
private void ReadMp4File(Stream fileStream, string fileName) { if (stream != null) { stream.Close(); } BackgroundWorker backgroundWorker = new BackgroundWorker(); Exception exceptionError = null; backgroundWorker.DoWork += delegate { try { stream = new Mp4Stream(fileStream); file = new Mp4File(stream); List <Mp4Box> unknowBoxes = file.Boxes.FindAll(b => b is Mp4UnknownBox); if (unknowBoxes.Count > 1) { throw new Exception("Too many unknow boxes."); } View.Dispatcher.Invoke(new Action(delegate { this.View.RootNode = BuildTree(file, new FileInfo(fileName).Name); controller.RemoveViews(); })); } catch (Exception ex) { exceptionError = ex; } }; ProgressWindow progressWindow = new ProgressWindow(); progressWindow.Worker = backgroundWorker; progressWindow.ShowDialog(); if (exceptionError != null) { throw exceptionError; } }
/// <inheritdoc/> public void UpdateEpisode(string fileName, Episode episode, IDictionary <MediaTrackType, string>?languages = default) { var file = Mp4File.Open(fileName); Update(file, episode, MediaKind.TVShow, languages); if (file.Tags is not null) { // episode file.Tags.EpisodeNumber = ValueOrNull(episode.Number); file.Tags.SeasonNumber = ValueOrNull(episode.Season); file.Tags.TVShow = episode.Show; file.Tags.EpisodeId = episode.Id; file.Tags.TVNetwork = episode.Network; file.Tags.ContentId = episode.Part; } file.Save();
public override async Task <StatusHandler> ProcessAsync(LibraryBook libraryBook) { OnBegin(libraryBook); OnStreamingBegin($"Begin converting {libraryBook} to mp3"); try { var m4bPath = AudibleFileStorage.Audio.GetPath(libraryBook.Book.AudibleProductId); m4bBook = new Mp4File(m4bPath, FileAccess.Read); m4bBook.ConversionProgressUpdate += M4bBook_ConversionProgressUpdate; fileSize = m4bBook.InputStream.Length; OnTitleDiscovered(m4bBook.AppleTags.Title); OnAuthorsDiscovered(m4bBook.AppleTags.FirstAuthor); OnNarratorsDiscovered(m4bBook.AppleTags.Narrator); OnCoverImageDiscovered(m4bBook.AppleTags.Cover); using var mp3File = File.OpenWrite(Path.GetTempFileName()); var result = await Task.Run(() => m4bBook.ConvertToMp3(mp3File)); m4bBook.InputStream.Close(); mp3File.Close(); var proposedMp3Path = Mp3FileName(m4bPath); var realMp3Path = FileUtility.SaferMoveToValidPath(mp3File.Name, proposedMp3Path); OnFileCreated(libraryBook, realMp3Path); var statusHandler = new StatusHandler(); if (result == ConversionResult.Failed) { statusHandler.AddError("Conversion failed"); } return(statusHandler); } finally { OnStreamingCompleted($"Completed converting to mp3: {libraryBook.Book.Title}"); OnCompleted(libraryBook); } }
/// <inheritdoc/> public void UpdateVideo(string fileName, Video video, IDictionary <MediaTrackType, string>?languages = default) { if (video is Episode episode) { this.UpdateEpisode(fileName, episode, languages); } else if (video is Movie movie) { this.UpdateMovie(fileName, movie, languages); } else { var file = Mp4File.Open(fileName); var mediaType = file.Tags is null ? MediaKind.NotSet : file.Tags.MediaType; Update(file, video, mediaType, languages); file.Save(); } }
internal TrackInfo(Mp4File mp4) { var sam = mp4.audioTrackSample; MediaInfo in4 = mp4.audioTrack.info; maxBytesInFrame = in4.mediaInformation.sampleTable.maxBytesInFrame; sampleRate = (int)(sam.sampleRateInt >> 16); bitsPerSample = sam.bitsPerSample; channelsCount = sam.channelCount; if (sam is MP4AudioSampleEntry) { audioCodec = eAudioCodec.AAC; uint sampleDelta = in4.mediaInformation.sampleTable.timeToSample[0].sampleDelta; uint timeScale = in4.timeScale; long samples = ((long)sampleDelta * sampleRate) / timeScale; samplesPerFrame = checked ((int)samples); if (16 != bitsPerSample) { throw new NotSupportedException("Currently, the library only supports 16-bit samples"); } decoderConfigBlob = mp4.audioTrackSample.audioSpecificConfig; strippedHeader = null; return; } if (sam is Ac3AudioSampleEntry) { audioCodec = eAudioCodec.AC3; decoderConfigBlob = null; strippedHeader = null; if (maxBytesInFrame > IO.Dolby.liba52.maxEncodedBuffer) { throw new ArgumentException($"Sample entry specified { maxBytesInFrame } bytes / frame, this exceeds the codec limit of { IO.Dolby.liba52.maxEncodedBuffer }"); } samplesPerFrame = IO.Dolby.liba52.samplesPerFrame; return; } throw new ApplicationException("Unrecognized audio codec"); }
public bool Step2_DownloadAndCombine() { DecryptProgressUpdate?.Invoke(this, 0); if (File.Exists(OutputFileName)) { FileExt.SafeDelete(OutputFileName); } FileStream outFile = File.OpenWrite(OutputFileName); aaxFile.SetDecryptionKey(downloadLicense.AudibleKey, downloadLicense.AudibleIV); aaxFile.ConversionProgressUpdate += AaxFile_ConversionProgressUpdate; var decryptionResult = OutputFormat == OutputFormat.Mp4a ? aaxFile.ConvertToMp4a(outFile, downloadLicense.ChapterInfo) : aaxFile.ConvertToMp3(outFile); aaxFile.ConversionProgressUpdate -= AaxFile_ConversionProgressUpdate; aaxFile.Close(); downloadLicense.ChapterInfo = aaxFile.Chapters; if (decryptionResult == ConversionResult.NoErrorsDetected && coverArt is not null && OutputFormat == OutputFormat.Mp4a) { //This handles a special case where the aaxc file doesn't contain cover art and //Libation downloaded it instead (Animal Farm). Currently only works for Mp4a files. using var decryptedBook = new Mp4File(OutputFileName, FileAccess.ReadWrite); decryptedBook.AppleTags?.SetCoverArt(coverArt); decryptedBook.Save(); decryptedBook.Close(); } nfsPersister.Dispose(); DecryptProgressUpdate?.Invoke(this, 0); return(decryptionResult == ConversionResult.NoErrorsDetected && !isCanceled); }
public static VideoSampleReader create(Mp4File mp4) { TrackMetadata track = mp4.videoTrack; if (null == track) { throw new ApplicationException("The MP4 doesn’t have a video track"); } VideoSampleEntry vse = mp4.videoTrackSample; switch (vse.naluLengthSize) { case 4: return(new VideoSampleReader4(mp4)); case 3: return(new VideoSampleReader3(mp4)); } // The specs also defines 1 and 2 bytes versions. // Slightly harder to handle as we need to expand the samples, 3 bytes is the minimum length of NALU start code in Annex B bitstream. throw new NotImplementedException(); }
/// <summary> /// /// </summary> /// <param name="obj"></param> private void Open(object obj) { try { OpenFileDialog openFileDialog = new OpenFileDialog(); //openFileDialog.Filter = "MP4 Files (*.mp4,*.m4a,*.ismv,*.mov,*.qlv)|*.mp4;*.m4a;*.ismv;*.mov;*.qlv|All Files (*.*)|*.*"; openFileDialog.Filter = "MP4 Files (*.mp4,*.m4a,*.ismv,*.mov)|*.mp4;*.m4a;*.ismv;*.mov|All Files (*.*)|*.*"; openFileDialog.FilterIndex = 1; if (openFileDialog.ShowDialog() == true) { if (stream != null) { stream.Close(); } BackgroundWorker backgroundWorker = new BackgroundWorker(); Exception exceptionError = null; backgroundWorker.DoWork += delegate(object s, DoWorkEventArgs args) { try { stream = new Mp4Stream(openFileDialog.OpenFile()); file = new Mp4File(stream); List <Mp4Box> unknowBoxes = file.Boxes.FindAll(b => b is Mp4UnknownBox); //if (unknowBoxes.Count > 1) // throw new Exception("Too many unknow boxes."); View.Dispatcher.Invoke(new Action(delegate { this.View.RootNode = BuildTree(file, new FileInfo(openFileDialog.FileName).Name); controller.RemoveViews(); })); } catch (Exception ex) { exceptionError = ex; } }; ProgressWindow progressWindow = new ProgressWindow(); progressWindow.Worker = backgroundWorker; progressWindow.ShowDialog(); if (exceptionError != null) { throw exceptionError; } } } catch { MessageBox.Show("Error loading mp4 file", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } }
public Reader(Mp4File mp4) { stream = mp4.reader.stream; sampleReader = new SampleReader(mp4.audioTrack); }
public VideoSampleReader3(Mp4File mp4) : base(mp4) { }
public VideoSampleReader(Mp4File mp4) { stream = mp4.reader.stream; sampleReader = new SampleReader(mp4.videoTrack); }