GithubHelp home page GithubHelp logo

mp-mediainfo's Introduction

MP-MediaInfo

MP-MediaInfo is .NET wrapper for MediaArea MediaInfo and use native packages NuGet Badge and NuGet Badge.

Build status

Features

  • Wraps the MediaInfo library
  • Provides properties for almost all information available using the MediaInfo library
  • Targets .NET Framework, .NET Standard, .NET 5, .NET 6

Available packages

Framework Package
.NET Framework 4.0 NuGet Badge
.NET Framework 4.5 NuGet Badge
.NET Standard 2.0 NuGet Badge
.NET Standard 2.1 NuGet Badge
.NET 5.0 NuGet Badge
.NET 6.0 NuGet Badge

Installation

There are 2 packages for .NET Core and .NET Framework. If your project is designed to run only on Windows and you are not using .NET Core, use the .NET Framework package. .NET Core package is designed for ASP.NET Core services only.

.NET Core

dotnet add package MediaInfo.Wrapper.Core --version 21.9.3

.NET Framework

Install-Package MediaInfo.Wrapper -Version 21.9.3

Usage

Add to usings:

using MediaInfo;

Instantiate an object of class MediaInfoWrapper, providing the full path to the media file and logger instance if it is required.

var media = new MediaInfoWrapper(mediaFileLocation);

Check successfully parsing of the parameters of the media file.

if (media.Success)
{
    ...
}

Retrieve technical and tag data from the video or audio file:

var containerFormat = media.Format;
var mediaHasVideo = media.HasVideo;
var videoBitRate = media.VideoRate;
foreach (var stream in media.AudioStreams)
{
    var codec = stream.Codec;
}

Demo application

ASP.NET Core demo application is available which shows the usage of the package, serialization and running from the docker container. Code from this demo should not be used in production code, the code is merely to demonstrate the usage of this package.

Dependencies

Make sure that the following dependencies are installed in the operating system before starting the project

.NET Core package supports next operating systems

Operation system Version
MacOS 10.15 (Catalina), 11 (Big Sur)
Ubuntu 16.04, 18.04, 20.04 and 21.04
CenOS 7 and above
Fedora 32 and above
OpenSUSE 15.2 and Tumbleweed
RedHat 7 and above
Debian 9 and above
Arch Linux
Windows 7 and above
Docker buster

MacOS

Some dependencies are available with MacPorts. To install MacPorts: https://guide.macports.org/#installing

port install zlib curl zenlib

Ubuntu

sudo apt-get update
sudo apt-get install libzen0v5 libmms0 zlib1g zlibc libnghttp2-14 librtmp1 curl libcurl4-gnutls-dev libglib2.0-dev

CentOS

CentOS 7

sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo yum -y update
sudo yum -y install zlib curl libzen bzip2 libcurl
sudo rpm -ivh https://download1.rpmfusion.org/free/el/updates/7/x86_64/l/libmms-0.6.4-2.el7.x86_64.rpm

CentOS 8

sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
sudo yum -y update
sudo yum -y install zlib curl libzen bzip2 libcurl
sudo rpm -ivh https://download1.rpmfusion.org/free/el/updates/8/x86_64/l/libmms-0.6.4-8.el8.x86_64.rpm

Fedora

sudo dnf update
sudo dnf -y install zlib curl libzen openssl libmms

OpenSUSE

sudo zypper refresh
sudo zypper update -y
sudo zypper install -y zlib curl libmms0 openssl libnghttp2-14

RedHat

RedHat 7

sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo yum -y update
sudo yum -y install zlib curl libzen bzip2 libcurl
sudo rpm -ivh https://download1.rpmfusion.org/free/el/updates/7/x86_64/l/libmms-0.6.4-2.el7.x86_64.rpm

RedHat 8

sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
sudo yum -y update
sudo yum -y install zlib curl libzen bzip2 libcurl
sudo rpm -ivh https://download1.rpmfusion.org/free/el/updates/8/x86_64/l/libmms-0.6.4-8.el8.x86_64.rpm

Debian

sudo apt-get update
sudo apt-get install libzen0v5 libmms0 openssl zlib1g zlibc libnghttp2-14 librtmp1 curl libcurl4-gnutls-dev libglib2.0

Windows

Windows package contains all dependencies and does not required any actions.

ArchLinux

sudo pacman -Syu
sudo pacman -S libcurl-gnutls libzen libmms libssh librtmp0

Docker

.NET Core 3.1

FROM mcr.microsoft.com/dotnet/aspnet:3.1
RUN apt-get update && apt-get install -y libzen0v5 libmms0 openssl zlib1g zlibc libnghttp2-14 librtmp1 curl libcurl4-gnutls-dev libglib2.0

.NET 5.0

FROM mcr.microsoft.com/dotnet/aspnet:5.0
RUN apt-get update && apt-get install -y libzen0v5 libmms0 openssl zlib1g zlibc libnghttp2-14 librtmp1 curl libcurl4-gnutls-dev libglib2.0

.NET 6.0

FROM mcr.microsoft.com/dotnet/aspnet:6.0
RUN apt-get update && apt-get install -y libzen0v5 libmms0 openssl zlib1g zlibc libnghttp2-14 librtmp1 curl libcurl4-gnutls-dev libglib2.0

mp-mediainfo's People

Contributors

bpoxy avatar doskabouter avatar jtone123 avatar yartat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

mp-mediainfo's Issues

Is it a BUG when create a new instance? - v21.9.3

Version 21.9.3

When I new an instance like this

var videoStream = new MediaInfoWrapper(fileName).BestVideoStream;

It will throw an exception

Value cannot be null. (Parameter 'logger')

image

The code in source MediaInfoWrapper.cs

image

Is it a BUG?

Improve logging or return error

When trying to get the info from a corrupted file, there's nothing in the log, and also no property on the MediaInfoWrapper instance that can be checked for errors.

Native MediaInfo library is not staticlly linked in Wrapper.Core under Ubuntu

NOTE; I'm not sure if this is a bug report or a feature request, So i'll try to be clear about what im getting and what im expecting either way.

When running under Ubuntu 18.04 LTS and using the Wrapper.Core package, libmediainfo.so is being loaded from the runtimes/ubuntu-18.04-x64 folder.

On a fresh Ubuntu 18.04 machine, loading of the native libmediainfo.so library fails. Inspection shows it is not statically linked, requiring the installation of libzen(0v5) and libmms(0) before it works.

Is that intended? Is it possible to provide a statically linked version or perhaps provide a readme that indicates this?

LanguageMediaStreamBuilder.cs no longer retrieves language correctly

Commit "Refactored project structure" has broken the retrieval of stream languages.

In MediaInfo.Wrapper/Builder/LanguageMediaStreamBuilder.cs, the new code:
var language = Get((int)NativeMethods.Generic.Generic_Language, InfoKind.Text).ToLower();
does not fetch the language short name.

The previous code:
var language = Get("Language").ToLower();
fetches the language short name correctly, e.g. "en".

Analyzing files with special characters

If I pass in a filepath with special characters like "³" for example for the Movie "[REC]³" I get the following output:

dbug: MediaInfo.MovieService[0]
2023-04-13T14:36:25.883272712Z       Analyzing media /mnt/media-data/movies/[REC]³ Genesis (2012)/[REC]³ Genesis (2012).mkv.
2023-04-13T14:36:25.883318982Z dbug: MediaInfo.MovieService[0]
2023-04-13T14:36:25.883328632Z       MediaInfo library was loaded. (handle=139712803286768, version=MediaInfoLib - v21.09)
2023-04-13T14:36:25.883338682Z warn: MediaInfo.MovieService[0]
2023-04-13T14:36:25.883341682Z       MediaInfo library has not been opened media /mnt/media-data/movies/[REC]³ Genesis (2012)/[REC]³ Genesis (2012).mkv
2023-04-13T14:36:25.883345492Z dbug: MediaInfo.MovieService[0]
2023-04-13T14:36:25.883347982Z       Process /mnt/media-data/movies/[REC]³ Genesis (2012)/[REC]³ Genesis (2012).mkv was completed successfully. Video=0, Audio=0, Subtitle=0

If I rename the folder to "[REC]3" everything works fine.
However, renaming is not really an option for me, so is there anything that I can do?

If I use MediaInfo from the CLI it can parse the file just fine.

LanguageMediaStream.Default is always false

Hey, I have multiple mkv movies with ac3 audio tracks that has a Default flag. When inspecting them with the MediaInfo program, I can verify that each movie has an ac3 track with the flag set to "Yes". Yet when using your wrapper the default flag aka. LanguageMediaStream.Default always appears as false? From my tests this is a proplem for both video and audio streams.

All MediaInfo properties are 0 or null

All my trials to get any information out of a .mkv file failed.
In a C# .NET Framework 4.6.1 Console Application, I have a simple code line like this:
var miWrapper = new MediaInfoWrapper(filePath);
In the Visual Studio Debugger, all property values of miWrapper are shown as null or 0.
I'm quite sure that I'm making a silly mistake.
A problem is, I couldn’t find a project in the Internet, that just does something simple like the above.
If you know of any simple example or if you could provide one, I would very appreciate.
When I just have the code to get one or two valid properties, I'll be able to do all the rest as I want.

Streaming/Byte-Wise usage

Hi there,

is it possible to use the wrapper on a streaming/byte-wise usage?
On an older version of your wrapper, i made some modifications to be able to push byte-arrays of the file contents into a method and get the mediainfo after i have pushed all data from file to this method. But that was 1+ years ago and i'm not able to maintain this "private fork". So i wanted to know, if this is possible with the current version of your wrapper.
Basically i was utilizing "OpenBufferContinue" with "Option("File_IsSeekable", "0");" and "OpenBufferInit(FileSize, 0L);".

Why have i done this?
I have some larger files i need to get media info from. Beside this, i also calculate some other file hashes of these files. Because of that, i do read those files byte per byte and push those bytes to the "consumers" i need/want to have informations from.

My modified MediaInfoWrapper.cs:
Methods of interest should be:

  • public MediaInfoWrapper(long FileSize, string pathToDll, ILogger logger = null)
  • public bool AddBytesToRead(byte[] bytesToRead, int offset, int length)
  • public bool FinalizeReadBytes()
  • private void ExtractInfo(Stream FileStream, string pathToDll, NumberFormatInfo providerNumber)
using MediaInfo.Builder;
using MediaInfo.Model;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;

namespace MediaInfo
{
  public class MediaInfoWrapper
  {
    private static readonly Dictionary<string, bool> SubTitleExtensions = new Dictionary<string, bool>()
    {
      {
        ".AQT",
        true
      },
      {
        ".ASC",
        true
      },
      {
        ".ASS",
        true
      },
      {
        ".DAT",
        true
      },
      {
        ".DKS",
        true
      },
      {
        ".IDX",
        true
      },
      {
        ".JS",
        true
      },
      {
        ".JSS",
        true
      },
      {
        ".LRC",
        true
      },
      {
        ".MPL",
        true
      },
      {
        ".OVR",
        true
      },
      {
        ".PAN",
        true
      },
      {
        ".PJS",
        true
      },
      {
        ".PSB",
        true
      },
      {
        ".RT",
        true
      },
      {
        ".RTF",
        true
      },
      {
        ".S2K",
        true
      },
      {
        ".SBT",
        true
      },
      {
        ".SCR",
        true
      },
      {
        ".SMI",
        true
      },
      {
        ".SON",
        true
      },
      {
        ".SRT",
        true
      },
      {
        ".SSA",
        true
      },
      {
        ".SST",
        true
      },
      {
        ".SSTS",
        true
      },
      {
        ".STL",
        true
      },
      {
        ".SUB",
        true
      },
      {
        ".TXT",
        true
      },
      {
        ".VKT",
        true
      },
      {
        ".VSF",
        true
      },
      {
        ".ZEG",
        true
      }
    };
    private readonly ILogger _logger;
    private readonly string _filePath;
    private readonly bool Is64BitProcess;
    private readonly string RealPathToDll;
    private readonly MediaInfo.MediaInfo _mi;

    public MediaInfoWrapper(string filePath, ILogger logger = null)
      : this(filePath, Environment.Is64BitProcess ? ".\\x64" : ".\\x86", logger)
    {
    }

    public MediaInfoWrapper(string filePath, string pathToDll, ILogger logger)
    {
      this._filePath = filePath;
      this._logger = logger;
      logger.LogDebug("Analyzing media {0}.", (object) filePath);
      this.VideoStreams = (IList<VideoStream>) new List<VideoStream>();
      this.AudioStreams = (IList<AudioStream>) new List<AudioStream>();
      this.Subtitles = (IList<SubtitleStream>) new List<SubtitleStream>();
      this.Chapters = (IList<ChapterStream>) new List<ChapterStream>();
      this.MenuStreams = (IList<MenuStream>) new List<MenuStream>();
      if (string.IsNullOrEmpty(filePath))
      {
        this.MediaInfoNotloaded = true;
        logger.LogError("Media file name to processing is null or empty");
      }
      else
      {
        string pathToDll1 = ((string) null).IfExistsPath("./", logger).IfExistsPath(pathToDll, logger).IfExistsPath(Path.GetDirectoryName(typeof (MediaInfoWrapper).Assembly.Location), logger).IfExistsPath(Path.IsPathRooted(pathToDll) ? (string) null : Path.Combine(Path.GetDirectoryName(typeof (MediaInfoWrapper).Assembly.Location), pathToDll), logger);
        if (string.IsNullOrEmpty(pathToDll1))
        {
          logger.LogError("MediaInfo.dll was not found");
          this.MediaInfoNotloaded = true;
        }
        else
        {
          bool flag1 = filePath.IsLiveTv();
          bool flag2 = filePath.IsLiveTv();
          bool flag3 = filePath.IsRtsp();
          bool flag4 = filePath.IsAvStream();
          if (flag3)
          {
            this.MediaInfoNotloaded = true;
            logger.LogInformation("Media file is RTSP");
          }
          else
          {
            if (flag2 | flag1)
            {
              string[] files = Directory.GetFiles(Path.GetDirectoryName(filePath), Path.GetFileName(filePath) + "*.ts");
              if ((uint) files.Length > 0U)
              {
                filePath = files[0];
              }
              else
              {
                this.MediaInfoNotloaded = true;
                logger.LogInformation("Media file is " + (flag1 ? "TV" : (flag2 ? "radio" : (flag3 ? "RTSP" : string.Empty))));
                return;
              }
            }
            NumberFormatInfo providerNumber = new NumberFormatInfo()
            {
              NumberDecimalSeparator = "."
            };
            try
            {
              if (!flag4)
              {
                if (filePath.EndsWith(".ifo", StringComparison.OrdinalIgnoreCase))
                {
                  this._logger.LogDebug("Detects DVD. Processing DVD information");
                  filePath = this.ProcessDvd(filePath, pathToDll1, providerNumber);
                }
                else if (filePath.EndsWith(".bdmv", StringComparison.OrdinalIgnoreCase))
                {
                  this._logger.LogDebug("Detects BD.");
                  this.IsBluRay = true;
                  filePath = Path.GetDirectoryName(filePath);
                  this.Size = MediaInfoWrapper.GetDirectorySize(filePath);
                }
                else
                  this.Size = new FileInfo(filePath).Length;
                this.HasExternalSubtitles = !string.IsNullOrEmpty(filePath) && MediaInfoWrapper.CheckHasExternalSubtitles(filePath);
                if (this.HasExternalSubtitles)
                  this._logger.LogDebug("Found external subtitles");
              }
              this.ExtractInfo(filePath, pathToDll1, providerNumber);
              logger.LogDebug(string.Format("Process file {0} was completed successfully. Video={1}, Audio={2}, Subtitle={3}", (object) filePath, (object) this.VideoStreams.Count, (object) this.AudioStreams.Count, (object) this.Subtitles.Count));
            }
            catch (Exception ex)
            {
              logger.LogError(ex, "Error processing media file");
            }
          }
        }
      }
    }

    public void WriteInfo()
    {
      this._logger.LogInformation("Inspecting media    : " + this._filePath);
      if (this.MediaInfoNotloaded)
      {
        this._logger.LogWarning("MediaInfo.dll was not loaded!");
      }
      else
      {
        this._logger.LogDebug("DLL version         : " + this.Version);
        this._logger.LogDebug(string.Format("Media duration      : {0}", (object) TimeSpan.FromMilliseconds((double) this.Duration)));
        ILogger logger1 = this._logger;
        IList<AudioStream> audioStreams1 = this.AudioStreams;
        string message1 = string.Format("Has audio           : {0}", (object) ((audioStreams1 != null ? audioStreams1.Count : 0) > 0));
        object[] objArray1 = new object[0];
        logger1.LogDebug(message1, objArray1);
        this._logger.LogDebug(string.Format("Has video           : {0}", (object) this.HasVideo));
        this._logger.LogDebug(string.Format("Has subtitles       : {0}", (object) this.HasSubtitles));
        this._logger.LogDebug(string.Format("Has chapters        : {0}", (object) this.HasChapters));
        this._logger.LogDebug(string.Format("Is DVD              : {0}", (object) this.IsDvd));
        this._logger.LogDebug(string.Format("Is Blu-Ray disk     : {0}", (object) this.IsBluRay));
        if (this.HasVideo)
        {
          ILogger logger2 = this._logger;
          VideoStream bestVideoStream1 = this.BestVideoStream;
          string message2 = string.Format("Video duration      : {0}", (object) (bestVideoStream1 != null ? bestVideoStream1.Duration : TimeSpan.MinValue));
          object[] objArray2 = new object[0];
          logger2.LogDebug(message2, objArray2);
          this._logger.LogDebug(string.Format("Video frame rate    : {0}", (object) this.Framerate));
          this._logger.LogDebug(string.Format("Video width         : {0}", (object) this.Width));
          this._logger.LogDebug(string.Format("Video height        : {0}", (object) this.Height));
          this._logger.LogDebug("Video aspect ratio  : " + this.AspectRatio);
          this._logger.LogDebug("Video codec         : " + this.VideoCodec);
          this._logger.LogDebug("Video scan type     : " + this.ScanType);
          this._logger.LogDebug(string.Format("Is video interlaced : {0}", (object) this.IsInterlaced));
          this._logger.LogDebug("Video resolution    : " + this.VideoResolution);
          ILogger logger3 = this._logger;
          VideoStream bestVideoStream2 = this.BestVideoStream;
          string message3 = string.Format("Video 3D mode       : {0}", (object) (StereoMode) (bestVideoStream2 != null ? (int) bestVideoStream2.Stereoscopic : 0));
          object[] objArray3 = new object[0];
          logger3.LogDebug(message3, objArray3);
          ILogger logger4 = this._logger;
          VideoStream bestVideoStream3 = this.BestVideoStream;
          string message4 = string.Format("Video HDR standard  : {0}", (object) (Hdr) (bestVideoStream3 != null ? (int) bestVideoStream3.Hdr : 0));
          object[] objArray4 = new object[0];
          logger4.LogDebug(message4, objArray4);
        }
        IList<AudioStream> audioStreams2 = this.AudioStreams;
        if ((audioStreams2 != null ? audioStreams2.Count : 0) > 0)
        {
          ILogger logger5 = this._logger;
          AudioStream bestAudioStream1 = this.BestAudioStream;
          string message5 = string.Format("Audio duration      : {0}", (object) (bestAudioStream1 != null ? bestAudioStream1.Duration : TimeSpan.MinValue));
          object[] objArray5 = new object[0];
          logger5.LogDebug(message5, objArray5);
          this._logger.LogDebug(string.Format("Audio rate          : {0}", (object) this.AudioRate));
          this._logger.LogDebug("Audio channels      : " + this.AudioChannelsFriendly);
          this._logger.LogDebug("Audio codec         : " + this.AudioCodec);
          ILogger logger6 = this._logger;
          AudioStream bestAudioStream2 = this.BestAudioStream;
          string message6 = string.Format("Audio bit depth     : {0}", (object) (bestAudioStream2 != null ? bestAudioStream2.BitDepth : 0));
          object[] objArray6 = new object[0];
          logger6.LogDebug(message6, objArray6);
        }
        if (this.HasSubtitles)
        {
          ILogger logger7 = this._logger;
          IList<SubtitleStream> subtitles = this.Subtitles;
          string message7 = string.Format("Subtitles count     : {0}", (object) (subtitles != null ? subtitles.Count : 0));
          object[] objArray7 = new object[0];
          logger7.LogDebug(message7, objArray7);
        }
        if (this.HasChapters)
        {
          ILogger logger8 = this._logger;
          IList<ChapterStream> chapters = this.Chapters;
          string message8 = string.Format("Chapters count      : {0}", (object) (chapters != null ? chapters.Count : 0));
          object[] objArray8 = new object[0];
          logger8.LogDebug(message8, objArray8);
        }
      }
    }

    private static long GetDirectorySize(string folderName) => !Directory.Exists(folderName) ? 0L : ((IEnumerable<string>) Directory.GetFiles(folderName)).Sum<string>((Func<string, long>) (x => new FileInfo(x).Length)) + ((IEnumerable<string>) Directory.GetDirectories(folderName)).Sum<string>((Func<string, long>) (x => MediaInfoWrapper.GetDirectorySize(x)));

    private string ProcessDvd(string filePath, string pathToDll, NumberFormatInfo providerNumber)
    {
      this.IsDvd = true;
      string str = Path.GetDirectoryName(filePath) ?? string.Empty;
      this.Size = MediaInfoWrapper.GetDirectorySize(str);
      string[] files = Directory.GetFiles(str, "*.BUP", SearchOption.TopDirectoryOnly);
      List<Tuple<string, int>> source = new List<Tuple<string, int>>();
      foreach (string fileName in files)
      {
        using (MediaInfo.MediaInfo mediaInfo = new MediaInfo.MediaInfo(pathToDll))
        {
          this.Version = mediaInfo.Option("Info_Version");
          mediaInfo.Open(fileName);
          if (mediaInfo.Get(StreamKind.General, 0, "Format_Profile") == "Program")
          {
            double result;
            double.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Duration"), NumberStyles.AllowDecimalPoint, (IFormatProvider) providerNumber, out result);
            source.Add(new Tuple<string, int>(fileName, (int) result));
          }
        }
      }
      if (source.Any<Tuple<string, int>>())
      {
        this.Duration = source.Max<Tuple<string, int>>((Func<Tuple<string, int>, int>) (x => x.Item2));
        filePath = source.First<Tuple<string, int>>((Func<Tuple<string, int>, bool>) (x => x.Item2 == this.Duration)).Item1;
      }
      return filePath;
    }

    private void ExtractInfo(string filePath, string pathToDll, NumberFormatInfo providerNumber)
    {
      using (MediaInfo.MediaInfo mediaInfo = new MediaInfo.MediaInfo(pathToDll))
      {
        if (mediaInfo.Handle == IntPtr.Zero)
        {
          this.MediaInfoNotloaded = true;
          this._logger.LogWarning("MediaInfo library was not loaded!");
        }
        else
        {
          this.Version = mediaInfo.Option("Info_Version");
          this._logger.LogDebug(string.Format("MediaInfo library was loaded. Handle={0} Version is {1}", (object) mediaInfo.Handle, (object) this.Version));
          IntPtr num1 = mediaInfo.Open(filePath);
          if (num1 == IntPtr.Zero)
          {
            this.MediaInfoNotloaded = true;
            this._logger.LogWarning("MediaInfo library has not been opened media " + filePath);
          }
          else
          {
            this._logger.LogDebug(string.Format("MediaInfo library successfully opened {0}. Handle={1}", (object) filePath, (object) num1));
            this.Format = mediaInfo.Get(StreamKind.General, 0, "Format");
            this.Profile = mediaInfo.Get(StreamKind.General, 0, "Format_Profile");
            this.FormatVersion = mediaInfo.Get(StreamKind.General, 0, "Format_Version");
            this.Codec = mediaInfo.Get(StreamKind.General, 0, "CodecID");
            int num2 = 0;
            this.Tags = new AudioTagBuilder(mediaInfo, 0).Build();
            this._logger.LogDebug(string.Format("Found {0} video streams.", (object) mediaInfo.CountGet(StreamKind.Video)));
            for (int position = 0; position < mediaInfo.CountGet(StreamKind.Video); ++position)
              this.VideoStreams.Add(new VideoStreamBuilder(mediaInfo, num2++, position).Build());
            if (this.Duration == 0)
            {
              double result;
              double.TryParse(mediaInfo.Get(StreamKind.Video, 0, 88), NumberStyles.AllowDecimalPoint, (IFormatProvider) providerNumber, out result);
              this.Duration = (int) result;
            }
            object obj1;
            if (this.VideoStreams.Count == 1 && this.Tags.GeneralTags.TryGetValue((NativeMethods.General) 1000, out obj1))
            {
              object obj2;
              this.VideoStreams[0].Stereoscopic = !this.Tags.GeneralTags.TryGetValue((NativeMethods.General) 1001, out obj2) ? ((bool) obj1 ? StereoMode.Stereo : StereoMode.Mono) : (StereoMode) obj2;
            }
            this._logger.LogDebug(string.Format("Found {0} audio streams.", (object) mediaInfo.CountGet(StreamKind.Audio)));
            for (int position = 0; position < mediaInfo.CountGet(StreamKind.Audio); ++position)
              this.AudioStreams.Add(new AudioStreamBuilder(mediaInfo, num2++, position).Build());
            if (this.Duration == 0)
            {
              double result;
              double.TryParse(mediaInfo.Get(StreamKind.Audio, 0, 70), NumberStyles.AllowDecimalPoint, (IFormatProvider) providerNumber, out result);
              this.Duration = (int) result;
            }
            this._logger.LogDebug(string.Format("Found {0} subtitle streams.", (object) mediaInfo.CountGet(StreamKind.Text)));
            for (int position = 0; position < mediaInfo.CountGet(StreamKind.Text); ++position)
              this.Subtitles.Add(new SubtitleStreamBuilder(mediaInfo, num2++, position).Build());
            this._logger.LogDebug(string.Format("Found {0} chapters.", (object) mediaInfo.CountGet(StreamKind.Other)));
            for (int position = 0; position < mediaInfo.CountGet(StreamKind.Other); ++position)
              this.Chapters.Add(new ChapterStreamBuilder(mediaInfo, num2++, position).Build());
            this._logger.LogDebug(string.Format("Found {0} menu items.", (object) mediaInfo.CountGet(StreamKind.Menu)));
            for (int position = 0; position < mediaInfo.CountGet(StreamKind.Menu); ++position)
              this.MenuStreams.Add(new MenuStreamBuilder(mediaInfo, num2++, position).Build());
            this.MediaInfoNotloaded = this.VideoStreams.Count == 0 && this.AudioStreams.Count == 0 && this.Subtitles.Count == 0;
            if (this.MediaInfoNotloaded)
              this.SetPropertiesDefault();
            else
              this.SetupProperties(mediaInfo);
          }
        }
      }
    }

    private void SetPropertiesDefault()
    {
      this.VideoCodec = string.Empty;
      this.VideoResolution = string.Empty;
      this.ScanType = string.Empty;
      this.AspectRatio = string.Empty;
      this.AudioCodec = string.Empty;
      this.AudioChannelsFriendly = string.Empty;
    }

    private void SetupProperties(MediaInfo.MediaInfo mediaInfo)
    {
      this.BestVideoStream = this.VideoStreams.OrderByDescending<VideoStream, double>((Func<VideoStream, double>) (x => (double) ((long) x.Width * (long) x.Height * (long) x.BitDepth * (x.Stereoscopic == StereoMode.Mono ? 1L : 2L)) * x.FrameRate * (x.Bitrate <= 1E-07 ? 1.0 : x.Bitrate))).FirstOrDefault<VideoStream>();
      this.VideoCodec = this.BestVideoStream?.CodecName ?? string.Empty;
      double? nullable1 = this.BestVideoStream?.Bitrate;
      int? nullable2 = nullable1.HasValue ? new int?((int) nullable1.GetValueOrDefault()) : new int?();
      this.VideoRate = nullable2.GetValueOrDefault();
      this.VideoResolution = this.BestVideoStream?.Resolution ?? string.Empty;
      VideoStream bestVideoStream1 = this.BestVideoStream;
      this.Width = bestVideoStream1 != null ? bestVideoStream1.Width : 0;
      VideoStream bestVideoStream2 = this.BestVideoStream;
      this.Height = bestVideoStream2 != null ? bestVideoStream2.Height : 0;
      VideoStream bestVideoStream3 = this.BestVideoStream;
      this.IsInterlaced = bestVideoStream3 != null && bestVideoStream3.Interlaced;
      VideoStream bestVideoStream4 = this.BestVideoStream;
      this.Framerate = bestVideoStream4 != null ? bestVideoStream4.FrameRate : 0.0;
      this.ScanType = this.BestVideoStream != null ? mediaInfo.Get(StreamKind.Video, this.BestVideoStream.StreamPosition, "ScanType").ToLower() : string.Empty;
      this.AspectRatio = this.BestVideoStream != null ? mediaInfo.Get(StreamKind.Video, this.BestVideoStream.StreamPosition, "DisplayAspectRatio") : string.Empty;
      this.AspectRatio = this.BestVideoStream != null ? (this.AspectRatio == "4:3" || this.AspectRatio == "1.333" ? "fullscreen" : "widescreen") : string.Empty;
      this.BestAudioStream = this.AudioStreams.OrderByDescending<AudioStream, double>((Func<AudioStream, double>) (x => (double) (x.Channel * 10000000) + x.Bitrate)).FirstOrDefault<AudioStream>();
      this.AudioCodec = this.BestAudioStream?.CodecName ?? string.Empty;
      nullable1 = this.BestAudioStream?.Bitrate;
      int? nullable3;
      if (!nullable1.HasValue)
      {
        nullable2 = new int?();
        nullable3 = nullable2;
      }
      else
        nullable3 = new int?((int) nullable1.GetValueOrDefault());
      nullable2 = nullable3;
      this.AudioRate = nullable2.GetValueOrDefault();
      nullable1 = this.BestAudioStream?.SamplingRate;
      int? nullable4;
      if (!nullable1.HasValue)
      {
        nullable2 = new int?();
        nullable4 = nullable2;
      }
      else
        nullable4 = new int?((int) nullable1.GetValueOrDefault());
      nullable2 = nullable4;
      this.AudioSampleRate = nullable2.GetValueOrDefault();
      AudioStream bestAudioStream = this.BestAudioStream;
      this.AudioChannels = bestAudioStream != null ? bestAudioStream.Channel : 0;
      this.AudioChannelsFriendly = this.BestAudioStream?.AudioChannelsFriendly ?? string.Empty;
    }

    private static bool CheckHasExternalSubtitles(string strFile)
    {
      if (string.IsNullOrEmpty(strFile))
        return false;
      string withoutExtension = Path.GetFileNameWithoutExtension(strFile);
      try
      {
        return ((IEnumerable<string>) Directory.GetFiles(Path.GetDirectoryName(strFile) ?? string.Empty, withoutExtension + "*")).Select<string, FileInfo>((Func<string, FileInfo>) (file => new FileInfo(file))).Any<FileInfo>((Func<FileInfo, bool>) (fi => MediaInfoWrapper.SubTitleExtensions.ContainsKey(fi.Extension.ToUpper())));
      }
      catch
      {
        return false;
      }
    }

    public bool HasVideo => this.VideoStreams.Count > 0;

    public bool Is3D => this.VideoStreams.Any<VideoStream>((Func<VideoStream, bool>) (x => (uint) x.Stereoscopic > 0U));

    public bool IsHdr => this.VideoStreams.Any<VideoStream>((Func<VideoStream, bool>) (x => (uint) x.Hdr > 0U));

    public IList<VideoStream> VideoStreams { get; }

    public VideoStream BestVideoStream { get; private set; }

    public string VideoCodec { get; private set; }

    public double Framerate { get; private set; }

    public int Width { get; private set; }

    public int Height { get; private set; }

    public string AspectRatio { get; private set; }

    public string ScanType { get; private set; }

    public bool IsInterlaced { get; private set; }

    public string VideoResolution { get; private set; }

    public int VideoRate { get; private set; }

    public IList<AudioStream> AudioStreams { get; }

    public AudioStream BestAudioStream { get; private set; }

    public string AudioCodec { get; private set; }

    public int AudioRate { get; private set; }

    public int AudioSampleRate { get; private set; }

    public int AudioChannels { get; private set; }

    public string AudioChannelsFriendly { get; private set; }

    public IList<SubtitleStream> Subtitles { get; }

    public bool HasSubtitles => this.HasExternalSubtitles || this.Subtitles.Count > 0;

    public bool HasExternalSubtitles { get; }

    public IList<ChapterStream> Chapters { get; }

    public bool HasChapters => this.Chapters.Count > 0;

    public IList<MenuStream> MenuStreams { get; }

    public bool HasMenu => this.MenuStreams.Count > 0;

    public bool IsDvd { get; private set; }

    public string Format { get; private set; }

    public string FormatVersion { get; private set; }

    public string Profile { get; private set; }

    public string Codec { get; private set; }

    public bool IsBluRay { get; }

    public bool MediaInfoNotloaded { get; private set; }

    public int Duration { get; private set; }

    public string Version { get; private set; }

    public long Size { get; private set; }

    public AudioTags Tags { get; private set; }

    public MediaInfoWrapper(long FileSize, ILogger logger = null)
      : this(FileSize, Environment.Is64BitProcess ? ".\\x64" : ".\\x86", logger)
    {
    }

    public MediaInfoWrapper(long FileSize, string pathToDll, ILogger logger = null)
    {
      this.Is64BitProcess = Environment.Is64BitProcess;
      if (string.IsNullOrEmpty(pathToDll))
        pathToDll = Environment.Is64BitProcess ? ".\\x64" : ".\\x86";
      this._logger = logger;
      logger.LogDebug("Initializing media for stream.");
      this.VideoStreams = (IList<VideoStream>) new List<VideoStream>();
      this.AudioStreams = (IList<AudioStream>) new List<AudioStream>();
      this.Subtitles = (IList<SubtitleStream>) new List<SubtitleStream>();
      this.Chapters = (IList<ChapterStream>) new List<ChapterStream>();
      this.RealPathToDll = ((string) null).IfExistsPath("./", logger).IfExistsPath(pathToDll, logger).IfExistsPath(Path.GetDirectoryName(typeof (MediaInfoWrapper).Assembly.Location), logger).IfExistsPath(Path.IsPathRooted(pathToDll) ? (string) null : Path.Combine(Path.GetDirectoryName(typeof (MediaInfoWrapper).Assembly.Location), pathToDll), logger);
      this.MenuStreams = (IList<MenuStream>) new List<MenuStream>();
      if (string.IsNullOrEmpty(this.RealPathToDll))
      {
        logger.LogError("MediaInfo.dll was not found");
        this.MediaInfoNotloaded = true;
      }
      else
      {
        this._mi = new MediaInfo.MediaInfo(this.RealPathToDll);
        this._mi = new MediaInfo.MediaInfo(pathToDll);
        this.Size = FileSize;
        this._mi.Option("File_IsSeekable", "0");
        this._mi.OpenBufferInit(FileSize, 0L);
      }
    }

    public MediaInfoWrapper(Stream inputStream, ILogger logger = null)
      : this(inputStream, Environment.Is64BitProcess ? ".\\x64" : ".\\x86", logger)
    {
    }

    public MediaInfoWrapper(Stream inputStream, string pathToDll, ILogger logger)
      : this(inputStream.Length, pathToDll, logger)
    {
      NumberFormatInfo providerNumber = new NumberFormatInfo()
      {
        NumberDecimalSeparator = "."
      };
      try
      {
        this.ExtractInfo(inputStream, this.RealPathToDll, providerNumber);
        logger.LogDebug(string.Format("Process file {0} was completed successfully. Video={1}, Audio={2}, Subtitle={3}", (object) inputStream, (object) this.VideoStreams.Count, (object) this.AudioStreams.Count, (object) this.Subtitles.Count));
      }
      catch (Exception ex)
      {
        logger.LogError(ex, "Error processing media file");
      }
    }

    public bool AddBytesToRead(byte[] bytesToRead, int offset, int length)
    {
      if (offset > 0)
      {
        byte[] numArray = new byte[length];
        Array.Copy((Array) bytesToRead, offset, (Array) numArray, 0, length);
        bytesToRead = numArray;
      }
      GCHandle gcHandle = GCHandle.Alloc((object) bytesToRead, GCHandleType.Pinned);
      IntPtr num = this._mi.OpenBufferContinue(gcHandle.AddrOfPinnedObject(), (IntPtr) length);
      gcHandle.Free();
      return ((int) num & 8) != 8;
    }

    public bool FinalizeReadBytes()
    {
      NumberFormatInfo providerNumber = new NumberFormatInfo()
      {
        NumberDecimalSeparator = "."
      };
      bool flag;
      try
      {
        this._mi.OpenBufferFinalize();
        this.ExtractData(this._mi, providerNumber);
        flag = true;
      }
      catch (Exception ex)
      {
        flag = false;
      }
      return flag;
    }

    private void ExtractData(MediaInfo.MediaInfo MI, NumberFormatInfo providerNumber)
    {
      this.Format = MI.Get(StreamKind.General, 0, "Format");
      this.Profile = MI.Get(StreamKind.General, 0, "Format_Profile");
      this.FormatVersion = MI.Get(StreamKind.General, 0, "Format_Version");
      this.Codec = MI.Get(StreamKind.General, 0, "CodecID");
      int num = 0;
      this.Tags = new AudioTagBuilder(MI, 0).Build();
      this._logger.LogDebug(string.Format("Found {0} video streams.", (object) MI.CountGet(StreamKind.Video)));
      for (int position = 0; position < MI.CountGet(StreamKind.Video); ++position)
        this.VideoStreams.Add(new VideoStreamBuilder(MI, num++, position).Build());
      if (this.Duration == 0)
      {
        double result;
        double.TryParse(MI.Get(StreamKind.Video, 0, 88), NumberStyles.AllowDecimalPoint, (IFormatProvider) providerNumber, out result);
        this.Duration = (int) result;
      }
      object obj1;
      if (this.VideoStreams.Count == 1 && this.Tags.GeneralTags.TryGetValue((NativeMethods.General) 1000, out obj1))
      {
        object obj2;
        this.VideoStreams[0].Stereoscopic = !this.Tags.GeneralTags.TryGetValue((NativeMethods.General) 1001, out obj2) ? ((bool) obj1 ? StereoMode.Stereo : StereoMode.Mono) : (StereoMode) obj2;
      }
      this._logger.LogDebug(string.Format("Found {0} audio streams.", (object) MI.CountGet(StreamKind.Audio)));
      for (int position = 0; position < MI.CountGet(StreamKind.Audio); ++position)
        this.AudioStreams.Add(new AudioStreamBuilder(MI, num++, position).Build());
      if (this.Duration == 0)
      {
        double result;
        double.TryParse(MI.Get(StreamKind.Audio, 0, 70), NumberStyles.AllowDecimalPoint, (IFormatProvider) providerNumber, out result);
        this.Duration = (int) result;
      }
      this._logger.LogDebug(string.Format("Found {0} subtitle streams.", (object) MI.CountGet(StreamKind.Text)));
      for (int position = 0; position < MI.CountGet(StreamKind.Text); ++position)
        this.Subtitles.Add(new SubtitleStreamBuilder(MI, num++, position).Build());
      this._logger.LogDebug(string.Format("Found {0} chapters.", (object) MI.CountGet(StreamKind.Other)));
      for (int position = 0; position < MI.CountGet(StreamKind.Other); ++position)
        this.Chapters.Add(new ChapterStreamBuilder(MI, num++, position).Build());
      this._logger.LogDebug(string.Format("Found {0} menu items.", (object) MI.CountGet(StreamKind.Menu)));
      for (int position = 0; position < MI.CountGet(StreamKind.Menu); ++position)
        this.MenuStreams.Add(new MenuStreamBuilder(MI, num++, position).Build());
      this.MediaInfoNotloaded = this.VideoStreams.Count == 0 && this.AudioStreams.Count == 0 && this.Subtitles.Count == 0;
      if (this.MediaInfoNotloaded)
        this.SetPropertiesDefault();
      else
        this.SetupProperties(MI);
    }

    private void ExtractInfo(Stream FileStream, string pathToDll, NumberFormatInfo providerNumber)
    {
      using (MediaInfo.MediaInfo MI = new MediaInfo.MediaInfo(pathToDll))
      {
        if (MI.Handle == IntPtr.Zero)
        {
          this.MediaInfoNotloaded = true;
          this._logger.LogWarning("MediaInfo library was not loaded!");
        }
        else
        {
          this.Version = MI.Option("Info_Version");
          this._logger.LogDebug(string.Format("MediaInfo library was loaded. Handle={0} Version is {1}", (object) MI.Handle, (object) this.Version));
          if (!FileStream.CanSeek)
          {
            MI.Option("File_IsSeekable", "0");
            MI.OpenBufferInit(FileStream.Length, 0L);
            int num1;
            IntPtr num2;
            do
            {
              byte[] buffer1 = new byte[65536];
              num1 = FileStream.Read(buffer1, 0, buffer1.Length);
              GCHandle gcHandle = GCHandle.Alloc((object) buffer1, GCHandleType.Pinned);
              IntPtr buffer2 = gcHandle.AddrOfPinnedObject();
              num2 = MI.OpenBufferContinue(buffer2, (IntPtr) num1);
              gcHandle.Free();
            }
            while ((int) num2 != 0 && FileStream.CanRead && num1 > 0);
          }
          else
          {
            MI.OpenBufferInit(FileStream.Length, 0L);
            int num3;
            do
            {
              byte[] buffer3 = new byte[65536];
              num3 = FileStream.Read(buffer3, 0, buffer3.Length);
              GCHandle gcHandle = GCHandle.Alloc((object) buffer3, GCHandleType.Pinned);
              IntPtr buffer4 = gcHandle.AddrOfPinnedObject();
              IntPtr num4 = MI.OpenBufferContinue(buffer4, (IntPtr) num3);
              gcHandle.Free();
              if (((int) num4 & 8) != 8)
              {
                long get = MI.OpenBufferContinueGoToGet();
                if (get != -1L)
                {
                  long fileOffset = FileStream.Seek(get, SeekOrigin.Begin);
                  MI.OpenBufferInit(FileStream.Length, fileOffset);
                }
              }
              else
                break;
            }
            while (FileStream.CanRead && num3 > 0);
          }
          MI.OpenBufferFinalize();
          this.ExtractData(MI, providerNumber);
        }
      }
    }
  }
}

not work on iis

the default function to get native dll retrun error path iis

MediaInfo.dll not found when building for x86 or for x64

This issue seems very similar to #2 and possibly related to #3.

When I build a new project explicitly targeting x86 or x64 directly, MediaInfo.dll and its related dependencies are all copied to the general output directory (e.g. bin\x86\Debug\MediaInfo.dll), but when I build the project with the Any CPU platform selected, MediaInfo.dll and related dependencies are copied into a subfolder for each architecture (e.g. bin\Debug\x86\MediaInfo.dll).

MediaInfo.Wrapper.dll always expects to find MediaInfo.dll in a subdirectory which causes the Any CPU version to work and the x86-specific version to fail (with MediaInfoNotloaded set to true).

We require our project to target x86 specifically for other reasons, so the only workaround I can see to address this (without forking this project) is to add a post build step to move those five MediaInfo files (libcrypto-1_1.dll, libcurl.dll, libssh2.dll, libssl-1_1.dll and MediaInfo.dll) into a new x86 subdirectory.

I've been able to reproduce this fairly trivially in a standalone project as follows:

  1. Create a new console project in Visual Studio

  2. Add MediaInfo.Wrapper as a NuGet dependency for your project

  3. Add an example video to the project (mine is named testvideo-5s.mp4) and set it to copy to the output directory

  4. In Program.cs, add the following code:

     var info = new MediaInfoWrapper("testvideo-5s.mp4");
     
     if (info.MediaInfoNotloaded)
     {
         Console.WriteLine("Failed to load");
     }
     else
     {
         Console.WriteLine("Loaded successfully");
     }
    
  5. Set the project's configuration to build for the x86 platform only.

  6. Build and run, and observe "Failed to load"

  7. Set the project's configuration to build for Any CPU

  8. Build and run, and observe "Loaded successfully"

Usage in Docker with webapi

Using this nice wrapper in a .NET Core WebApi projects and all is good when running on the machine . Also works great when running on AWS in an elastic beans. No problems there.

Now I created a docker image and this is where it goes wrong:
The file filePath get's created as something like /tmp/adfexssd.tmp
It is stored in that directory as well. But the info returned is empty, just nulls and zero's.

        IFormFile file = commercialAsset.UploadFile;
        var filePath = Path.GetTempFileName();
        await using (var filestream = File.Create(filePath))
        {
            await file.CopyToAsync(filestream);
        }
        // get some mediainfo
        MediaInfo.MediaInfoWrapper _mediaInfoWrapper = new MediaInfoWrapper(filePath);

I assume the wrapper does not understand the linux path.
Any way to solve this?

*) It looks like the files from the mediainfo package do not make it into to docker image somehow. Maybe related to issue #14, it also returns 'mediainfo file not loaded' when using the logging.

Revise license

Hi,

This repo says it is licensed under the MIT license. However, it is clearly distributing GPL-licensed files, as evidenced by the headers at the top of source files.

Please revise the license on this repo to make it clear to users that the code they are using is GPL, not MIT.

Examples (very random sampling):

// MediaPortal is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.

// MediaPortal is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.

// MediaPortal is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.

Thanks.

MediaInfoWrapper should be JSON serializable / deserializable

For working with information extracted from a media file within e.g. REST APIs, it is required to have JSON serialization/deserialization capabilities. Principally, the class is serializable and deserializable, however, all read-only properties like BestVideoStream, Duration, Framerate etc. are empty after deserialization. The method SetupProperties is a) private and b) requires some information which is obiously not there when deserializing the class. In first step it would help to make the method public and at least to be able to handle mediaInfo == null condition.

MediaInfo.Open works on windows but not on Ubuntu

Hello, I hope someone can help me out here :) I have pretty basic example, which works fine on Windows but not on Ubuntu 20.04. File does exist and I'm keep getting "No video streams in file" on Ubuntu without any error message. Is there a way how to figure out what's going on?

if (!System.IO.File.Exists(filename))
{
    return new { Error = "File does not exists" };
}

var mw1 = new MediaInfo.MediaInfo();
mw1.Option("ParseSpeed", "0");
mw1.Open(filename);            

var videostreamcount = mw1.CountGet(StreamKind.Video, 0);
if (videostreamcount > 0)
{
    var _height = mw1.Get(StreamKind.Video, 0, "Height");
    var _scanType = mw1.Get(StreamKind.Video, 0, "ScanType");
    var _isInterlaced = _scanType == "Interlaced";
    var _duration = mw1.Get(StreamKind.Video, 0, "Duration");
    return new { Height = _height, ScanType = _scanType, IsInterlaced = _isInterlaced, Duration = _duration };
}
else
{
    return new { Error = "No video streams in file" };
}

MediaInfo.Native package not correct ?

I'm unable to use the MediaInfo.Wrapper because the MediaInfo.Native package is not currently working.
I think that:

1] the targets file from MediaInfo.Native is not appended to the project where I import this NuGet.

2] Also If I try to add the import manually:
I see that the dll files are copied to the output (Debug/Release) folder into two sub-folders ("x64" and "x86").
But when running some code, the dll's are not found.

Wrapper language

Is there anyway to determinate the language like in the installed version of MediaInfo?

Resolution Determination is Too Strict

The current logic for determining resolution expects video dimensions to exactly match the resolution specification (or be larger).
e.g. For a video to be considered 1080p is must have width >= 1920 or height >= 1080.

However, sometimes videos are slightly cropped (due to black bars, etc.) and fail this test.
e.g. 1916 x 798 is considered 720p even though it should be 1080p.

I suggest introducing a bit of tolerance, similar to what is done on the NzbDrone projects.
The following is an excerpt from a method in the the Sonarr repository, to give you an idea of what I mean:

var width = localEpisode.MediaInfo.Width;
var height = localEpisode.MediaInfo.Height;


if (width >= 3200 || height >= 2100)
{
	_logger.Trace("Resolution {0}x{1} considered 2160p", width, height);
	return AugmentQualityResult.ResolutionOnly(2160, Confidence.MediaInfo);
}

if (width >= 1800 || height >= 1000)
{
	_logger.Trace("Resolution {0}x{1} considered 1080p", width, height);
	return AugmentQualityResult.ResolutionOnly(1080, Confidence.MediaInfo);
}

if (width >= 1200 || height >= 700)
{
	_logger.Trace("Resolution {0}x{1} considered 720p", width, height);
	return AugmentQualityResult.ResolutionOnly(720, Confidence.MediaInfo);
}

Thoughts?

How to get the "extra" field

Hi @yartat ,

I used your MediaInfo.Wrapper.Core lib, and found I can't find the field "extra", but it can be analyzed from the MediaInfo GUI. Can you help me to get those fields like the screenshot? Many thanks!

image

BitrateMode is not accessible

Hello,
the BitRateMode (CBR, VBR) is unfortunately not accessible. It would be great if you could add it to the published properties. Thank you.

Network / HTTP stream support ?

Hello,
Is there a reason why HTTP / Network stream support is not enabled ? I see there are quite a few checks to detect if a provided string/path is network or HTTP file in FileExtensions.cs but its not made use of in main MediaWrapper class.

I wanted to get mediainfo for remote video url (http/https file) as well but not able to, it just throws MediaInfoNotLoaded.

Linux - MediaInfo.dll was not loaded!

I'm currently trying to get the MediaInfo.Wrapper.Core up and running but I get the error message MediaInfo.dll was not loaded! when I try to use the sample project.

I'm running Fedora 34 and as I can see in the runtimes folder in my bin directory there is no folder for Fedora 34.
I've installed the needed dependencies and MediaInfoLib itself is also installed (MediaInfoLib - v21.03).

I can the mediainfo CLI command just fine.
Could someone please give me any guidance on how to get this running?

Memory Leak in MediaInfoWrapper Usage

When using the MediaInfoWrapper class to handle media file information in my application, I encounter a significant memory leak issue. Below is a snippet of the code:

var mediaInfo = new MediaInfoWrapper(filePath, _logger);
double totalSeconds = TimeSpan.FromMilliseconds(mediaInfo.Duration).TotalSeconds;
int roundedSeconds = (int)Math.Round(totalSeconds);
I need to process 2860 media files, and I've noticed that the MediaInfoWrapper instances are not disposed of after their usage. Unfortunately, the MediaInfoWrapper class does not implement the IDisposable interface, which exacerbates the memory management issues. This oversight leads to increased memory consumption and potential application instability over time.

Could the implementation be updated to include IDisposable, or could another mechanism for proper resource management be provided?

Thank you.

Missing null check in TagHelper

Hey,

line 229: var coverDataItems = ((string)coverData).Split(new[] { " / " }, StringSplitOptions.RemoveEmptyEntries);

Is missing nullcheck, aka. ((string)coverData)?

And in line 234: "coverDataItems.Length" should be changed to "coverDataItems?.Length ?? 0"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.