-
Notifications
You must be signed in to change notification settings - Fork 11
Enhancements #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Enhancements #26
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,7 +22,7 @@ public void TestToString() | |
| voidPosition = 40 | ||
| }; | ||
|
|
||
| string json = mkvFile.ToString(); | ||
| string json = mkvFile.ToString().Replace("\r\n", "\n"); | ||
|
|
||
| json.Should().Be(""" | ||
| { | ||
|
|
@@ -35,10 +35,21 @@ public void TestToString() | |
| "flagDefaultByteNumber": 0, | ||
| "flagForced": true, | ||
| "flagForcedByteNumber": 0, | ||
| "flagHearingImpaired": false, | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated to match new Track properties |
||
| "flagHearingImpairedByteNumber": 0, | ||
| "flagVisualImpaired": false, | ||
| "flagVisualImpairedByteNumber": 0, | ||
| "flagTextDescriptions": false, | ||
| "flagTextDescriptionsByteNumber": 0, | ||
| "flagOriginal": false, | ||
| "flagOriginalByteNumber": 0, | ||
| "flagCommentary": false, | ||
| "flagCommentaryByteNumber": 0, | ||
| "flagTypebytenumber": 0, | ||
| "type": "subtitle", | ||
| "name": "", | ||
| "language": "eng" | ||
| "language": "eng", | ||
| "codecId": null, | ||
| } | ||
| ], | ||
| "seekList": [], | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Diagnostics; | ||
| using System.IO; | ||
| using System.Linq; | ||
| using MediaInfo; | ||
| using MediaInfo.Model; | ||
| using MatroskaLib.Types; | ||
| using Microsoft.Extensions.Logging.Abstractions; | ||
|
|
||
| namespace MatroskaLib.Helpers; | ||
|
|
||
| public static class MediaInfoHelper | ||
| { | ||
| public static void GetAllTrackFormats(Stream stream, IEnumerable<Track> tracks) | ||
| { | ||
|
|
||
| try | ||
| { | ||
| if (!stream.CanSeek) | ||
| { | ||
| Debug.WriteLine($"Stream is not seekable, cannot use MediaInfo"); | ||
| return results; | ||
| } | ||
|
|
||
| long originalPosition = stream.Position; | ||
| stream.Position = 0; | ||
|
|
||
| var mediaInfo = new MediaInfoWrapper(stream, NullLogger.Instance); | ||
|
|
||
| stream.Position = originalPosition; | ||
|
|
||
| if (!mediaInfo.Success) | ||
| { | ||
| Debug.WriteLine($"MediaInfo failed to read from stream"); | ||
| return results; | ||
| } | ||
|
|
||
| Debug.WriteLine($"MediaInfo found {mediaInfo.AudioStreams?.Count ?? 0} audio streams, {mediaInfo.Subtitles?.Count ?? 0} subtitle streams"); | ||
|
|
||
| foreach (var track in tracks) | ||
| { | ||
| if (track.type == TrackTypeEnum.audio) | ||
| { | ||
| if (mediaInfo.AudioStreams != null && mediaInfo.AudioStreams.Any()) | ||
| { | ||
| var audioStream = mediaInfo.AudioStreams.FirstOrDefault(a => a.Id == (int)track.number); | ||
|
|
||
| if (audioStream != null) | ||
| { | ||
| Debug.WriteLine($"Track #{track.number} (audio) - Format: '{audioStream.Format}', CodecDesc: '{audioStream.CodecDescription}', Bitrate: {audioStream.Bitrate}"); | ||
| var format = string.Empty; | ||
|
|
||
| if (!string.IsNullOrEmpty(audioStream.CodecDescription)) | ||
| format = audioStream.CodecDescription; | ||
| else if (!string.IsNullOrEmpty(audioStream.CodecFriendly)) | ||
| format = audioStream.CodecFriendly; | ||
| else if (!string.IsNullOrEmpty(audioStream.Format)) | ||
| format = audioStream.Format; | ||
|
|
||
| track.detectedFormat = format ?? string.Empty; | ||
| track.bitrate = audioStream.Bitrate; | ||
| } | ||
| else | ||
| { | ||
| Debug.WriteLine($"Track #{track.number} (audio) - No matching MediaInfo stream found"); | ||
| } | ||
| } | ||
| } | ||
| else if (track.type == TrackTypeEnum.subtitle) | ||
| { | ||
| var subtitleStream = mediaInfo.Subtitles?.FirstOrDefault(s => s.Id == (int)track.number); | ||
|
|
||
| if (subtitleStream != null) | ||
| { | ||
| Debug.WriteLine($"Track #{track.number} (subtitle) - Format: '{subtitleStream.Format}'"); | ||
| track.detectedFormat = subtitleStream.Format ?? string.Empty; | ||
| track.bitrate = 0; // Subtitles typically don't have a bitrate, so we set it to 0 | ||
| } | ||
| else | ||
| { | ||
| Debug.WriteLine($"Track #{track.number} (subtitle) - No matching MediaInfo stream found"); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| catch (Exception ex) | ||
| { | ||
| Debug.WriteLine($"MediaInfoHelper exception: {ex.Message}"); | ||
| Debug.WriteLine($"Stack trace: {ex.StackTrace}"); | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,8 @@ | |
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="NEbml" Version="1.1.0.5"/> | ||
| <PackageReference Include="MediaInfo.Wrapper.Core" Version="21.9.3" /> | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MediaInfo.Wrapper.Core gets us a lot more decoding. |
||
| <PackageReference Include="NEbml" Version="1.1.0.5" /> | ||
| </ItemGroup> | ||
|
|
||
| </Project> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.IO; | ||
| using System.Linq; | ||
| using MatroskaLib.Helpers; | ||
| using MatroskaLib.Types; | ||
| using NEbml.Core; | ||
| using NEbml.Matroska; | ||
|
|
@@ -17,7 +19,7 @@ public static List<MkvFile> ReadMkvFiles(string[] filePaths) | |
| var tracks = new List<Track>(); | ||
| var seekList = new List<Seek>(); | ||
|
|
||
| using var fileStream = File.Open(filePath, FileMode.Open); | ||
| using var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Allows FileShare.Read keeps us from breaking while we (or someone else) has the file open for read-only access. |
||
| var reader = new EbmlReader(fileStream); | ||
|
|
||
| int? seekHeadCheckSum = _ReadSeekHead(reader, fileStream, seekList); | ||
|
|
@@ -44,6 +46,23 @@ public static List<MkvFile> ReadMkvFiles(string[] filePaths) | |
|
|
||
| return mkvFiles; | ||
| } | ||
|
|
||
| public static void LoadMediaInfoForFile(MkvFile mkvFile) | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lazy-load of the rest of the media information |
||
| { | ||
| if (mkvFile.mediaInfoLoaded) | ||
| return; | ||
|
|
||
| try | ||
| { | ||
| using var fileStream = File.Open(mkvFile.filePath, FileMode.Open, FileAccess.Read, FileShare.Read); | ||
| MediaInfoHelper.GetAllTrackFormats(fileStream, mkvFile.tracks); | ||
| mkvFile.mediaInfoLoaded = true; | ||
| } | ||
| catch (System.Exception ex) | ||
| { | ||
| System.Diagnostics.Debug.WriteLine($"Failed to load MediaInfo for {mkvFile.filePath}: {ex.Message}"); | ||
| } | ||
| } | ||
|
|
||
| private static int? _ReadSeekHead(EbmlReader reader, FileStream fileStream, List<Seek> seekList) | ||
| { | ||
|
|
||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixes problems where the build environment serialization uses CR/LF instead of just LF