VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "clsMediaInfo"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Attribute VB_Ext_KEY = "SavedWithClassBuilder6" ,"Yes"
Attribute VB_Ext_KEY = "Top_Level" ,"Yes"
' -------------------------------------------------------------------------------
'
'   AVStoDVD - by MrC
'   File: clsMediaInfo.cls
'   Purpose: Class that handle MediaInfo
'   Requires: modUtil.bas
'
' -------------------------------------------------------------------------------


' Define class Enum

#If MEDIAINFO_NO_ENUMS Then
#Else

Private Enum MediaInfo_stream_C
    MediaInfo_Stream_General
    MediaInfo_Stream_Video
    MediaInfo_Stream_Audio
    MediaInfo_Stream_Text
    MediaInfo_Stream_Chapters
    MediaInfo_Stream_Image
    MediaInfo_Stream_Menu
    MediaInfo_Stream_Max
End Enum

Private Enum MediaInfo_info_C
    MediaInfo_Info_Name
    MediaInfo_Info_Text
    MediaInfo_Info_Measure
    MediaInfo_Info_Options
    MediaInfo_Info_Name_Text
    MediaInfo_Info_Measure_Text
    MediaInfo_Info_Info
    MediaInfo_Info_HowTo
    MediaInfo_Info_Max
End Enum

#End If


' Define class Type

Private Type GeneralMediaInfoType
    MediaInfoVersion As String
    PathName As String
    Filename As String
    FileExt As String
    FileSize As String
    Format As String
    VideoTracksCount As String
    AudioTracksCount As String
    TextTracksCount As String
    Time As String
End Type

Private Type VideoMediaInfoType
    ID As String
    StreamOrder As String
    Time As String
    Compression As String
    BitRateMode As String
    AvgBitRate As String
    MinBitRate As String
    MaxBitRate As String
    Width As String
    Height As String
    DisplayAspectRatio As String
    PixelAspectRatio As String
    FrameAspectRatio As String
    Standard As String
    FrameRateMode As String
    FPS As String
    FrameCount As String
    ScanType As String
    ScanOrder As String
    ColorSpace As String
    ColorCoefficients As String
End Type

Private Type AudioMediaInfoType
    ID(0 To 99) As String
    StreamOrder(0 To 99) As String
    Time(0 To 99) As String
    Compression(0 To 99) As String
    BitRateMode(0 To 99) As String
    AvgBitRate(0 To 99) As String
    Channels(0 To 99) As String
    SampleRate(0 To 99) As String
    Resolution(0 To 99) As String
    Language(0 To 99) As String
    Delay(0 To 99) As String
End Type

Private Type TextMediaInfoType
    ID(0 To 99) As String
    StreamOrder(0 To 99) As String
    Format(0 To 99) As String
    Language(0 To 99) As String
    Title(0 To 99) As String
End Type

Private Type ChaptersMediaInfoType
    List As String
End Type


' Define class Variables

Private GeneralInfo As GeneralMediaInfoType
Private VideoInfo As VideoMediaInfoType
Private AudioInfo As AudioMediaInfoType
Private TextInfo As TextMediaInfoType
Private ChaptersInfo As ChaptersMediaInfoType


' APIs

Private Declare Sub MediaInfo_Close Lib "MediaInfo.dll" (ByVal Handle As Long)
Private Declare Sub MediaInfo_Delete Lib "MediaInfo.dll" (ByVal Handle As Long)
'Private Declare Function MediaInfo_Count_Get Lib "MediaInfo.dll" (ByVal Handle As Long, ByVal StreamKind As MediaInfo_stream_C, ByVal StreamNumber As Long) As Long
Private Declare Function MediaInfo_Get Lib "MediaInfo.dll" (ByVal Handle As Long, ByVal StreamKind As MediaInfo_stream_C, ByVal StreamNumber As Long, ByVal Parameter As Long, ByVal InfoKind As MediaInfo_info_C, ByVal SearchKind As MediaInfo_info_C) As Long
Private Declare Function MediaInfo_GetI Lib "MediaInfo.dll" (ByVal Handle As Long, ByVal StreamKind As MediaInfo_stream_C, ByVal StreamNumber As Long, ByVal Parameter As Long, ByVal InfoKind As MediaInfo_info_C) As Long
'Private Declare Function MediaInfo_Inform Lib "MediaInfo.dll" (ByVal Handle As Long, ByVal Reserved As Long) As Long
Private Declare Function MediaInfo_New Lib "MediaInfo.dll" () As Long
'Private Declare Function MediaInfo_New_Quick Lib "MediaInfo.dll" (ByVal File As Long, ByVal Options As Long) As Long
Private Declare Function MediaInfo_Open Lib "MediaInfo.dll" (ByVal Handle As Long, ByVal File As Long) As Long
'Private Declare Function MediaInfo_Open_Buffer Lib "MediaInfo.dll" (ByVal Handle As Long, Begin As Any, ByVal Begin_Size As Long, End_ As Any, ByVal End_Size As Long) As Long
Private Declare Function MediaInfo_Option Lib "MediaInfo.dll" (ByVal Handle As Long, ByVal Option_ As Long, ByVal value As Long) As Long
'Private Declare Function MediaInfo_Save Lib "MediaInfo.dll" (ByVal Handle As Long) As Long
'Private Declare Function MediaInfo_Set Lib "MediaInfo.dll" (ByVal Handle As Long, ByVal ToSet As Long, ByVal StreamKind As MediaInfo_stream_C, ByVal StreamNumber As Long, ByVal Parameter As Long, ByVal OldParameter As Long) As Long
'Private Declare Function MediaInfo_SetI Lib "MediaInfo.dll" (ByVal Handle As Long, ByVal ToSet As Long, ByVal StreamKind As MediaInfo_stream_C, ByVal StreamNumber As Long, ByVal Parameter As Long, ByVal OldParameter As Long) As Long
'Private Declare Function MediaInfo_State_Get Lib "MediaInfo.dll" (ByVal Handle As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)


' Media reading routine for all media files EXCEPT AviSynth Script (.avs) and DGIndex Project (.d2v)
Public Function ReadMediaInfo(MediaPathName As String, _
                              Optional MediaInfoPath As String, _
                              Optional bErrDisplay As Boolean = True, _
                              Optional bReadVideo As Boolean = True, _
                              Optional bReadAudio As Boolean = True, _
                              Optional bReadText As Boolean = True, _
                              Optional bReadChapters As Boolean = True, _
                              Optional bRunBackup As Boolean = True) As Boolean

    Dim Handle As Long
    Dim OrigCurDir As String
    Dim OrigMousePointer As MousePointerConstants
    Dim jj As Integer
    Dim Str As String
    Dim FRMOrig As String
    Dim FPSOrig As String
    Dim ChannOrig As String
    Dim ExpectedFrameCount As Long
    Dim BackupInfo As New clsMediaInfo
    Dim bBackup As Boolean
    
    On Error GoTo Err_Handling
    
    OrigMousePointer = Screen.MousePointer
    Screen.MousePointer = vbHourglass
    
    ReadMediaInfo = True
    OrigCurDir = CurDir
    If MediaInfoPath = "" Then MediaInfoPath = App.Path & "\Lib"
    ChDrive Left(MediaInfoPath, 2)
    ChDir MediaInfoPath
    
    ' Open MediaInfo handle
    Handle = MediaInfo_New()
    Call MediaInfo_Open(Handle, StrPtr(MediaPathName))
    
    ' Read General info
    With GeneralInfo
        .MediaInfoVersion = bStr(MediaInfo_Option(0, StrPtr("Info_Version"), StrPtr("")))
        .PathName = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_General, 0, StrPtr("CompleteName"), MediaInfo_Info_Text, MediaInfo_Info_Name))
        .Filename = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_General, 0, StrPtr("FileName"), MediaInfo_Info_Text, MediaInfo_Info_Name))
        .FileExt = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_General, 0, StrPtr("FileExtension"), MediaInfo_Info_Text, MediaInfo_Info_Name))
        .FileSize = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_General, 0, StrPtr("FileSize"), MediaInfo_Info_Text, MediaInfo_Info_Name))
        .Format = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_General, 0, StrPtr("Format"), MediaInfo_Info_Text, MediaInfo_Info_Name))
        .VideoTracksCount = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_General, 0, StrPtr("VideoCount"), MediaInfo_Info_Text, MediaInfo_Info_Name))
        .AudioTracksCount = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_General, 0, StrPtr("AudioCount"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            If Val(.AudioTracksCount) > 99 Then .AudioTracksCount = 99
        .TextTracksCount = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_General, 0, StrPtr("TextCount"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            If Val(.TextTracksCount) > 99 Then .TextTracksCount = 99
        .Time = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_General, 0, StrPtr("Duration"), MediaInfo_Info_Text, MediaInfo_Info_Name))
        ' Handle MediaInfo reading errors and start ReadAVSInfoF (works on video or audio tracks)
        If .FileSize > 0 Then
            If .Filename = "" Or .Format = "" Or .Time = "" Then
                bBackup = bReadVideo Or bReadAudio
            ElseIf .VideoTracksCount = "" Then
                bBackup = bReadVideo
            End If
        End If
        If bBackup = True And bRunBackup = True Then
            If BackupInfo.ReadAVSInfoF(MediaPathName, , , False) = True Then
                If .Filename = "" Then .Filename = BackupInfo.Filename
                If .Format = "" Then .Format = BackupInfo.Format
                If .Time = "" Then .Time = BackupInfo.Time
                If .VideoTracksCount = "" Then .VideoTracksCount = BackupInfo.VideoTracksCount
                If .AudioTracksCount = "" Then .AudioTracksCount = BackupInfo.AudioTracksCount
                If .MediaInfoVersion = "" Then
                    .MediaInfoVersion = BackupInfo.MediaInfoVersion
                Else
                    .MediaInfoVersion = .MediaInfoVersion & " + " & BackupInfo.MediaInfoVersion
                End If
            End If
        End If
        If .Filename = "" Then
            ReadMediaInfo = False
            If bErrDisplay = True Then MsgBox "Error reading '" & MediaPathName & "'. Please check the following list and then retry:" & vbCrLf & vbCrLf & "- AviSynth is not (correctly) installed" & vbCrLf & "- MediaInfo.dll is not found" & vbCrLf & "- Filename contains non-standard characters.", vbExclamation + vbOKOnly, App.Title & " (ReadMediaInfo)"
        ElseIf .Format = "" Then
            ReadMediaInfo = False
            If bErrDisplay = True Then MsgBox "Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "File format not recognized.", vbExclamation + vbOKOnly, App.Title & " (ReadMediaInfo)"
        ElseIf .VideoTracksCount = "" And bReadVideo = True Then
            ReadMediaInfo = False
            If bErrDisplay = True Then MsgBox "Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot detect any video tracks.", vbExclamation + vbOKOnly, App.Title & " (ReadMediaInfo)"
        End If
    End With
    If ReadMediaInfo = False Then GoTo Exit_Handling
    
    If bReadVideo = True Then
        ' Read Video info
        With VideoInfo
            .ID = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("ID"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .StreamOrder = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("FirstPacketOrder"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                If .StreamOrder = "" Then .StreamOrder = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("StreamOrder"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .Time = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("Duration"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                If .Time = "" Then .Time = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_General, 0, StrPtr("Duration"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .Compression = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("Codec/String"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .BitRateMode = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("BitRate_Mode"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .AvgBitRate = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("BitRate"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                If .AvgBitRate = "" Then .AvgBitRate = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("BitRate_Nominal"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                If Val(.AvgBitRate) < 0 Then .AvgBitRate = ""
            .MinBitRate = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("BitRate_Minimum"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .MaxBitRate = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("BitRate_Maximum"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .Width = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("Width"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .Height = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("Height"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .DisplayAspectRatio = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("DisplayAspectRatio"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .PixelAspectRatio = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("PixelAspectRatio"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                If .PixelAspectRatio = "" Then .PixelAspectRatio = "1"
            .FrameAspectRatio = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("DisplayAspectRatio_Original"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                If .FrameAspectRatio = "" And .Width <> "" And .Height <> "" Then .FrameAspectRatio = Replace(Round(Val(.Width) / Val(.Height), 3), ",", ".")
            .Standard = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("Standard"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .FrameRateMode = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("FrameRate_Mode"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .FPS = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("FrameRate"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                If .FPS = "" Then .FPS = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("FrameRate_Nominal"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .FrameCount = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("FrameCount"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .ScanType = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("ScanType"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .ScanOrder = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("ScanOrder"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .ColorSpace = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("ColorSpace"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            .ColorCoefficients = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("matrix_coefficients"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            ' FrameRateMode fix
            FRMOrig = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("FrameRate_Mode_Original"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            If FRMOrig <> "" And FRMOrig <> .FrameRateMode Then
                .FrameRateMode = ""   ' better to leave the variable empty if there is conflict between FrameRate_Mode and FrameRate_Mode_Original
            End If
            If .FrameRateMode = "VFR" And InStr(1, UCase(.Compression), "MPEG-2") <> 0 Then
                .FrameRateMode = "CFR"
            End If
            ' FrameRate Original fix
            FPSOrig = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("FrameRate_Original"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            If .FPS = "" Then
                .FPS = FPSOrig
            Else
                If Val(FPSOrig) > 0 And Val(.FPS) <> Val(FPSOrig) Then
                    If bErrDisplay = True Then
                        If MsgBox("Warning!" & vbCrLf & vbCrLf & "Media Container and Video Stream have different FrameRate tags:" & vbCrLf & vbCrLf & _
                                  "Media Container: " & Val(.FPS) & " fps" & vbCrLf & _
                                  "Video Stream: " & Val(FPSOrig) & " fps" & vbCrLf & vbCrLf & _
                                  "Press 'OK' for  " & Val(.FPS) & " fps    or    'Cancel' for  " & Val(FPSOrig) & " fps" & vbCrLf & _
                                  "(Press 'OK' if you do not know)", vbQuestion + vbOKCancel, App.Title & " (ReadMediaInfo)") = vbCancel Then
                            .FPS = FPSOrig
                        End If
                    Else
                        .FPS = FPSOrig
                    End If
                End If
            End If
            ' Video Time (and other properties) fix
            bBackup = False
            If .Time = "" Or .FrameCount = "" Then
                bBackup = bRunBackup
            End If
            If bBackup = True Then
                If BackupInfo.Time = "" Then
                    BackupInfo.ReadAVSInfoF MediaPathName, , , False
                End If
                If BackupInfo.VideoTime <> "" Then
                    If .Time = "" Then .Time = BackupInfo.VideoTime
                    If .Compression = "" Then .Compression = BackupInfo.VideoCompression
                    If .FrameCount = "" Then .FrameCount = BackupInfo.VideoFrameCount
                    If .FPS = "" Then .FPS = BackupInfo.VideoFPS
                    If .FrameRateMode = "" Then .FrameRateMode = BackupInfo.VideoFrameRateMode
                    If .ColorSpace = "" Then .ColorSpace = BackupInfo.VideoColorSpace
                    If .Width = "" Then .Width = BackupInfo.VideoWidth
                    If .Height = "" Then .Height = BackupInfo.VideoHeight
                    If .DisplayAspectRatio = "" Then
                        .DisplayAspectRatio = BackupInfo.VideoDAR
                        .FrameAspectRatio = BackupInfo.VideoFAR
                        .PixelAspectRatio = BackupInfo.VideoPAR
                    End If
                End If
            End If
            ' FrameCount check
            Select Case LCase(.ScanOrder)
            Case "2:2:2:2:2:2:2:2:2:2:2:3 pulldown"
                ExpectedFrameCount = Round(Val(.Time) / 1000 * 25, 0)
            Case "2:3 pulldown"
                ExpectedFrameCount = Round(Val(.Time) / 1000 * 29.97, 0)
            Case Else
                ExpectedFrameCount = Round(Val(.Time) / 1000 * Val(.FPS), 0)
            End Select
            If ExpectedFrameCount > 0 Then
                If .FrameCount = "" Then
                    .FrameCount = CStr(ExpectedFrameCount)
                Else
                    If InStr(1, UCase(.ScanOrder), "PULLDOWN") <> 0 Then
                        .FrameCount = CStr(ExpectedFrameCount)
                    ElseIf Abs(Val(.FrameCount) - ExpectedFrameCount) / ExpectedFrameCount > 0.2 Then
                        If bErrDisplay = True Then
                            If MsgBox("Warning!" & vbCrLf & vbCrLf & "MediaInfo has detected an abnormal Video frames value:" & vbCrLf & vbCrLf & _
                                      "Detected value: " & .FrameCount & " frames" & vbCrLf & _
                                      "Expected value: " & ExpectedFrameCount & " frames" & vbCrLf & vbCrLf & _
                                      "Press 'OK' for  " & ExpectedFrameCount & "    or    'Cancel' for  " & .FrameCount & vbCrLf & _
                                      "(Press 'OK' if you do not know)", vbQuestion + vbOKCancel, App.Title & " (ReadMediaInfo)") = vbOK Then
                                .FrameCount = CStr(ExpectedFrameCount)
                            End If
                        Else
                            .FrameCount = CStr(ExpectedFrameCount)
                        End If
                    End If
                End If
            End If
            If .FPS = "" Then
                If bErrDisplay = True Then
                    If MsgBox("Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot detect Framerate." & vbCrLf & vbCrLf & "Do you want to insert FrameRate value manually?", vbExclamation + vbYesNo, App.Title & " (ReadMediaInfo)") = vbYes Then
                        Do
                            .FPS = Replace(InputBox("Insert FrameRate [frames/seconds]:", App.Title & " (ReadMediaInfo)", "25"), ",", ".")
                            If Val(.FPS) <= 0 Then
                                MsgBox "Warning! FrameRate format is not valid.", vbCritical, App.Title & " (ReadMediaInfo)"
                            End If
                        Loop Until Val(.FPS) > 0
                    End If
                End If
            End If
            ' Adjusting mpeg2 avgbitrate MediaInfo readings
            If InStr(1, UCase(.Compression), "MPEG-2") <> 0 Then
                If .BitRateMode = "CBR" Then
                    Str = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Video, 0, StrPtr("BitRate_Nominal"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                    If Str <> "" Then .AvgBitRate = Str
                End If
                If .AvgBitRate = "" And Val(GeneralInfo.AudioTracksCount) = 0 And GeneralInfo.FileSize <> "" And .Time <> "" Then
                    .AvgBitRate = CStr(Int(Val(GeneralInfo.FileSize) / Val(.Time) * 1000 * 8))
                End If
            End If
        End With
    End If
    
    ' Read Audio info
    If bReadAudio = True And Val(GeneralInfo.AudioTracksCount) > 0 Then
        With AudioInfo
            For jj = 0 To Val(GeneralInfo.AudioTracksCount) - 1
                .ID(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("ID"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .StreamOrder(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("FirstPacketOrder"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                    If .StreamOrder(jj) = "" Then .StreamOrder(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("StreamOrder"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .Time(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("Duration"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                    If .Time(jj) = "" Then .Time(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_General, 0, StrPtr("Duration"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .Compression(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("Codec/String"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .AvgBitRate(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("BitRate"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                    If .AvgBitRate(jj) = "" Then bStr (MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("BitRate_Nominal"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .BitRateMode(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("BitRate_Mode"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                    If .BitRateMode(jj) = "" Then .BitRateMode(jj) = "CBR"
                .Channels(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("Channel(s)"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .SampleRate(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("SamplingRate"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .Resolution(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("Resolution"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .Language(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("Language"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .Delay(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("Video_Delay"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                ' Abnormal delay reading fix
                If Abs(Val(.Delay(jj))) > 5000 Then
                    If bErrDisplay = True Then
                        If MsgBox("Warning!" & vbCrLf & vbCrLf & "There is an abnormal delay in Audio Track ID " & .ID(jj) & ":" & vbCrLf & vbCrLf & _
                                  "Delay: " & Round(Val(.Delay(jj)) / 1000, 3) & " s" & vbCrLf & vbCrLf & _
                                  "Press 'OK' to reset it    or    'Cancel' to use that value anyway" & vbCrLf & _
                                  "(Press 'OK' if you do not know)", vbQuestion + vbOKCancel, App.Title & " (ReadMediaInfo)") = vbOK Then
                            .Delay(jj) = ""
                        End If
                    Else
                        .Delay(jj) = ""
                    End If
                End If
                ' Channels Original fix
                ChannOrig = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Audio, jj, StrPtr("Channel(s)_Original"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                If .Channels(jj) = "" Then
                    .Channels(jj) = ChannOrig
                Else
                    If Val(ChannOrig) > 0 And Val(.Channels(jj)) <> Val(ChannOrig) Then
                        If bErrDisplay = True Then
                            If MsgBox("Warning!" & vbCrLf & vbCrLf & "Audio Track ID " & .ID(jj) & " and Media Container have different Audio Channels tags:" & vbCrLf & vbCrLf & _
                                      "Audio Track ID " & .ID(jj) & ": " & ChannOrig & " channel(s)" & vbCrLf & _
                                      "Media Container: " & .Channels(jj) & " channel(s)" & vbCrLf & vbCrLf & _
                                      "Press 'OK' for  " & ChannOrig & " channel(s)   or    'Cancel' for  " & .Channels(jj) & " channel(s)" & vbCrLf & _
                                      "(Press 'OK' if you do not know)", vbQuestion + vbOKCancel, App.Title & " (ReadMediaInfo)") = vbOK Then
                                .Channels(jj) = ChannOrig
                            End If
                        Else
                            .Channels(jj) = ChannOrig
                        End If
                    End If
                End If
            Next jj
            ' Audio Time (and other properties) fix
            If .Time(0) = "" Then
                If BackupInfo.AudioTime(0) <> "" And bRunBackup = True Then
                    .Time(0) = BackupInfo.AudioTime(0)
                    If .BitRateMode(0) = "" Then .BitRateMode(0) = BackupInfo.AudioBitRateMode(0)
                    If .Channels(0) = "" Then .Channels(0) = BackupInfo.AudioChannels(0)
                    If .SampleRate(0) = "" Then .SampleRate(0) = BackupInfo.AudioSampleRate(0)
                    If .Resolution(0) = "" Then .Resolution(0) = BackupInfo.AudioResolution(0)
                    If .Compression(0) = "" Then .Compression(0) = BackupInfo.AudioCompression(0)
                End If
            End If
        End With
    End If

    ' Read Text (Subs) info
    If bReadText = True And Val(GeneralInfo.TextTracksCount) > 0 Then
        For jj = 0 To Val(GeneralInfo.TextTracksCount) - 1
            With TextInfo
                .ID(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Text, jj, StrPtr("ID"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .StreamOrder(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Text, jj, StrPtr("FirstPacketOrder"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                    If .StreamOrder(jj) = "" Then .StreamOrder(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Text, jj, StrPtr("StreamOrder"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .Format(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Text, jj, StrPtr("Format"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .Language(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Text, jj, StrPtr("Language"), MediaInfo_Info_Text, MediaInfo_Info_Name))
                .Title(jj) = bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Text, jj, StrPtr("Title"), MediaInfo_Info_Text, MediaInfo_Info_Name))
            End With
        Next jj
    End If

    ' Read Chapters Info (up to 99 chapters positions)
    If bReadChapters = True Then
        With ChaptersInfo
            For jj = Val(bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Menu, 0, StrPtr("Chapters_Pos_Begin"), MediaInfo_Info_Text, MediaInfo_Info_Name))) To Val(bStr(MediaInfo_Get(Handle, MediaInfo_Stream_Menu, 0, StrPtr("Chapters_Pos_End"), MediaInfo_Info_Text, MediaInfo_Info_Name)))
                Str = bStr(MediaInfo_GetI(Handle, MediaInfo_Stream_Menu, 0, jj, MediaInfo_Info_Name))
                If Str <> "" Then
                    .List = .List & Str & " "
                End If
            Next jj
            If Right(.List, 1) = " " Then .List = Left(.List, Len(.List) - 1)
        End With
    End If
    
    ' Calculating Time
    With GeneralInfo
        If Val(.Time) <= 0 Then
            If AudioInfo.Time(0) <> "" Then .Time = AudioInfo.Time(0)
            If VideoInfo.Time <> "" Then .Time = VideoInfo.Time
        End If
        If Val(.Time) <= 0 Then
            ReadMediaInfo = False
            If bErrDisplay = True Then
                If MsgBox("Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot detect Duration." & vbCrLf & vbCrLf & "Do you want to insert Duration manually?", vbExclamation + vbYesNo, App.Title & " (ReadMediaInfo)") = vbYes Then
                    Do
                        .Time = InputBox("Insert Duration [seconds]:" & vbCrLf & vbCrLf & "(1 hour is 3600 seconds)", App.Title & " (ReadMediaInfo)", "3600")
                        If Val(.Time) > 0 Then
                            .Time = .Time * 1000
                            If bReadVideo = True Then
                                VideoInfo.Time = .Time
                                If VideoInfo.FrameCount = "" Then
                                    VideoInfo.FrameCount = Int(Val(.Time) / 1000 * Val(VideoInfo.FPS))
                                End If
                            End If
                            If bReadAudio = True And Val(.AudioTracksCount) > 0 Then
                                AudioInfo.Time(0) = .Time
                            End If
                            ReadMediaInfo = True
                        ElseIf .Time <> "" Then
                            MsgBox "Warning! PlayTime format not valid.", vbCritical, App.Title & " (ReadMediaInfo)"
                        End If
                    Loop Until ReadMediaInfo = True Or Val(.Time) > 0
                End If
            End If
        End If
    End With
    
    ' Close MediaInfo handle
    Call MediaInfo_Close(Handle)
    Call MediaInfo_Delete(Handle)
    
    GoTo Exit_Handling
        
Err_Handling:
Select Case Err.Number
Case 9999
    Resume
Case Else
    If bErrDisplay = True Then MsgBox "Error " & Err.Number & vbCrLf & vbCrLf & Err.Description, vbCritical, App.Title & " (ReadMediaInfo)"
    ReadMediaInfo = False
End Select

Exit_Handling:
Set BackupInfo = Nothing
If Mid(OrigCurDir, 2, 1) = ":" Then
    ChDrive Left(OrigCurDir, 2)
End If
ChDir OrigCurDir
Screen.MousePointer = OrigMousePointer

End Function


' Media reading routine (FAST) for all media files INCLUDING AviSynth Script (.avs) and DGIndex Project (.d2v)
Public Function ReadAVSInfoF(MediaPathName As String, _
                            Optional TempPath As String, _
                            Optional AVSMeterPath As String, _
                            Optional bErrDisplay As Boolean = True) As Boolean

    Dim NumFile As Integer
    Dim sAVS As String
    Dim sLog As String
    Dim AVSMeterPathName As String
    Dim sArray
    Dim bSourceAVSorD2V As Boolean
    
    On Error GoTo Err_Handling
    
    Screen.MousePointer = vbHourglass

    If TempPath = "" Then TempPath = Environ("TEMP")
    If AVSMeterPath = "" Then AVSMeterPath = App.Path & "\AVSMeter"
    AVSMeterPathName = AVSMeterPath & "\AVSMeter.exe"
    Select Case UCase(Right(MediaPathName, 3))
    Case "AVS", "D2V"
        bSourceAVSorD2V = True
    Case Else
        bSourceAVSorD2V = False
    End Select
    If Dir(TempPath & "\AVSInfo.bat") <> "" Then Kill TempPath & "\AVSInfo.bat"
    If Dir(TempPath & "\AVSInfo.avs") <> "" Then Kill TempPath & "\AVSInfo.avs"
    
    ' Generate AVSInfo.avs file
    If bSourceAVSorD2V = False Then
        sAVS = "Import(""" & App.Path & "\Lib\A2DSource.avsi""" & ")" & vbCrLf & _
               "Try {" & vbCrLf & _
               "Audio = A2DAudioSource(""" & MediaPathName & """, CacheFolder=""" & TempPath & """)" & vbCrLf & _
               "}" & vbCrLf & _
               "Catch(Err_Msg) {" & vbCrLf & _
               "    Audio = BlankClip(audio_rate = 0)" & vbCrLf & _
               "}" & vbCrLf & _
               "Video = FFVideoSource(""" & MediaPathName & """, track=-1, cache=false, seekmode=0)" & vbCrLf & _
               "Return HasAudio(Audio) ? AudioDub(Video, Audio) : Video"
    Else
        If LCase(Right(MediaPathName, 4)) = ".d2v" Then
            sAVS = "LoadPlugin(""" & App.Path & "\DGIndex\DGDecode.dll""" & ")" & vbCrLf & _
                   "MPEG2Source(""" & MediaPathName & """)"
        Else
            sAVS = "Import(""" & MediaPathName & """)"
        End If
    End If
    NumFile = FreeFile
    Open TempPath & "\AVSInfo.avs" For Output As #NumFile
        Print #NumFile, sAVS
    Close #NumFile
    
    ' Generate AVSInfo.bat file
    NumFile = FreeFile
    Open TempPath & "\AVSInfo.bat" For Output As #NumFile
        Print #NumFile, """" & AVSMeterPathName & """ """ & TempPath & "\AVSInfo.avs" & """ -l -i"
    Close #NumFile
    DoEvents
    Sleep 500
    If Dir(TempPath & "\AVSInfo.bat") <> "" Then
        ReadAVSInfoF = CBool(Shell(TempPath & "\AVSInfo.bat", vbHide))
        If ReadAVSInfoF = False Then
            If bErrDisplay = True Then MsgBox "Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot run AVSInfo.bat", vbExclamation + vbOKOnly, App.Title & " (ReadAVSInfoF)"
            GoTo Exit_Handling
        Else
            Do
                Sleep 500
            Loop Until modUtil.FindRunningProcess(AVSMeterPathName) = 0 And Dir(TempPath & "\AVSInfo.log") <> ""
        End If
    End If
    DoEvents
    'modUtil.KillRunningProcess AVSMeterPathName

    NumFile = FreeFile
    If Dir(TempPath & "\AVSInfo.log") <> "" Then
        Open TempPath & "\AVSInfo.log" For Input As #NumFile
            Do Until EOF(NumFile)
                sLog = sLog & Input(1, #NumFile)
            Loop
        Close #NumFile
    End If
    If InStr(1, sLog, "Log file created with:") <> 0 And InStr(1, sLog, "AVSMeter") <> 0 Then
        With GeneralInfo
            .PathName = MediaPathName
            .Filename = Dir(MediaPathName)
            'FileExt
            'FileSize
            If bSourceAVSorD2V = False Then
                .Format = "Media"
            Else
                If LCase(Right(MediaPathName, 4)) = ".d2v" Then
                    .Format = "D2V"
                Else
                    .Format = "AVS"
                End If
            End If
            .MediaInfoVersion = "AVSMeter.exe"
        End With
        If Load_Str(sLog, "Number of frames") <> "" Then
            GeneralInfo.VideoTracksCount = "1"
            With VideoInfo
                sArray = Split(Load_Str(sLog, "Length (hh:mm:ss.ms)"), ":")
                .Time = (Val(sArray(0)) * 3600 + Val(sArray(1)) * 60 + Val(sArray(2))) * 1000
                If bSourceAVSorD2V = False Then
                    .Compression = "Unknown Video"
                Else
                    If LCase(Right(MediaPathName, 4)) = ".d2v" Then
                        .Compression = "DGIndex"
                    Else
                        .Compression = "AviSynth"
                    End If
                End If
                .Width = Load_Str(sLog, "Frame width")
                .Height = Load_Str(sLog, "Frame height")
                If Val(.Height) > 0 Then .FrameAspectRatio = Replace(Val(.Width) / Val(.Height), ",", ".")
                If .DisplayAspectRatio = "" Then .DisplayAspectRatio = .FrameAspectRatio
                If Val(.FrameAspectRatio) > 0 Then .PixelAspectRatio = Replace(Val(.DisplayAspectRatio) / Val(.FrameAspectRatio), ",", ".")
                .FrameRateMode = "CFR"
                .FPS = Load_Str(sLog, "Framerate")
                Do Until IsNumeric(.FPS) = True
                    .FPS = Left(.FPS, Len(.FPS) - 1)
                Loop
                .FPS = Replace(.FPS, " ", "")
                .FrameCount = Load_Str(sLog, "Number of frames")
                .ColorSpace = Load_Str(sLog, "Colorspace")
                'If LCase(Load_Str(sLog, "Interlaced")) = "yes" Then
                '    .ScanType = "Interlaced"
                'Else
                '    .ScanType = "Progressive"
                'End If
                '.ScanOrder = ""
            End With
        Else
            ReadAVSInfoF = False
            If bErrDisplay = True Then MsgBox "Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot detect Video Stream.", vbExclamation + vbOKOnly, App.Title & " (ReadAVSInfoF)"
        End If
        If IsNumeric(Load_Str(sLog, "Audio samples")) = True Then
            GeneralInfo.AudioTracksCount = "1"
            With AudioInfo
                .Compression(0) = IIf(bSourceAVSorD2V = True, "AviSynth", "Unknown Audio")
                .BitRateMode(0) = "CBR"
                .Channels(0) = Load_Str(sLog, "Audio channels")
                .SampleRate(0) = Load_Str(sLog, "Audio sample rate")
                .Resolution(0) = Load_Str(sLog, "Audio bits/sample")
                .Time(0) = CStr(Int(Val(Load_Str(sLog, "Audio samples")) * 1000 / Val(.SampleRate(0))))
                '.Delay(0) = ""
                If .Compression(0) = "" Then
                    ReadAVSInfoF = False
                    If bErrDisplay = True Then MsgBox "Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot detect Audio Stream.", vbExclamation + vbOKOnly, App.Title & " (ReadAVSInfoF)"
                End If
            End With
        End If
        With GeneralInfo
            If AudioInfo.Time(0) <> "" Then .Time = AudioInfo.Time(0)
            If VideoInfo.Time <> "" Then .Time = VideoInfo.Time
        End With
    Else
        ReadAVSInfoF = False
        If bErrDisplay = True Then MsgBox "Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot find a valid '" & TempPath & "\AVSInfo.log' file.", vbExclamation + vbOKOnly, App.Title & " (ReadAVSInfoF)"
    End If

    GoTo Exit_Handling

Err_Handling:
Select Case Err.Number
Case 9999   'fake
    Resume
Case Else
    If bErrDisplay = True Then MsgBox "Error " & Err.Number & vbCrLf & vbCrLf & Err.Description, vbCritical, App.Title & " (ReadAVSInfoF)"
    ReadAVSInfoF = False
End Select

Exit_Handling:
If ReadAVSInfoF = False Then
    If bErrDisplay = True Then
        MsgBox "Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot read Media.", vbExclamation + vbOKOnly, App.Title & " (ReadAVSInfoF)"
    End If
End If
If Dir(TempPath & "\AVSInfo.bat") <> "" Then Kill TempPath & "\AVSInfo.bat"
If Dir(TempPath & "\AVSInfo.avs") <> "" Then Kill TempPath & "\AVSInfo.avs"
If Dir(TempPath & "\AVSInfo.log") <> "" Then Kill TempPath & "\AVSInfo.log"
Screen.MousePointer = vbDefault

End Function


' Media reading routine (SLOW) for all media files INCLUDING AviSynth Script (.avs) and DGIndex Project (.d2v)
Public Function ReadAVSInfoS(MediaPathName As String, _
                             Optional TempPath As String, _
                             Optional AVSLoader As String, _
                             Optional A2DInfoLibPath As String, _
                             Optional bSourceAVSorD2V As Boolean = True, _
                             Optional bErrDisplay As Boolean = True) As Boolean

    Const TimeOut = 60 'seconds
    
    Dim NumFile As Integer
    Dim PathName As String
    Dim sAVS As String
    Dim sBAT As String
    Dim sTXT As String
    Dim StrMedia As String
    Dim TimeStart As Long
    Dim AVSLoaderPathName As String
    
    On Error GoTo Err_Handling
    
    Screen.MousePointer = vbHourglass

    If TempPath = "" Then TempPath = Environ("TEMP")
    'If AVSLoader = "" Then AVSLoader = "ffmpeg"
    If AVSLoader = "" Then AVSLoader = "AVSMeter"
    AVSLoaderPathName = App.Path & "\" & AVSLoader & "\" & AVSLoader & ".exe"
    If A2DInfoLibPath = "" Then A2DInfoLibPath = App.Path & "\Lib"
    
    If Dir(TempPath & "\AVSInfo.bat") <> "" Then Kill TempPath & "\AVSInfo.bat"
    If Dir(TempPath & "\AVSInfo.avs") <> "" Then Kill TempPath & "\AVSInfo.avs"
    If Dir(TempPath & "\AVSInfo.txt") <> "" Then Kill TempPath & "\AVSInfo.txt"
    
    If LCase(Right(MediaPathName, 4)) = ".d2v" Then
        PathName = Preferences.TempPath & "\AviSynthD.avs"
        NumFile = FreeFile
        Open PathName For Output As #NumFile
            Print #NumFile, "LoadPlugin(""" & App.Path & "\DGIndex\DGDecode.dll""" & ")" & vbCrLf & _
                            "MPEG2Source(""" & MediaPathName & """)"
        Close #NumFile
    Else
        PathName = MediaPathName
    End If
    sAVS = "Import(""" & A2DInfoLibPath & "\A2DInfo.avsi"")" & vbCrLf & _
           "A2DInfo(""" & PathName & """, """ & TempPath & "\AVSInfo.txt""" & ", " & IIf(bSourceAVSorD2V = True, "true", "false") & ")"
    NumFile = FreeFile
    Open TempPath & "\AVSInfo.avs" For Output As #NumFile
        Print #NumFile, sAVS
    Close #NumFile
    Select Case LCase(AVSLoader)
    Case "ffmpeg"
        sBAT = """" & AVSLoaderPathName & """ -i """ & TempPath & "\AVSInfo.avs""" & " -f rawvideo -y NUL"
    Case "avsmeter"
        sBAT = """" & AVSLoaderPathName & """ """ & TempPath & "\AVSInfo.avs"""
    End Select
    NumFile = FreeFile
    Open TempPath & "\AVSInfo.bat" For Output As #NumFile
        Print #NumFile, sBAT
    Close #NumFile
    DoEvents
    Sleep 500
    If Dir(TempPath & "\AVSInfo.bat") <> "" Then
        ReadAVSInfoS = CBool(Shell(TempPath & "\AVSInfo.bat", vbHide))
        If ReadAVSInfoS = False Then
            If bErrDisplay = True Then MsgBox "Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot run AVSInfo.bat", vbExclamation + vbOKOnly, App.Title & " (ReadAVSInfoS)"
            GoTo Exit_Handling
        Else
            TimeStart = Timer
            Do
                If Timer - TimeStart > TimeOut Then
                    Exit Do
                End If
                Sleep 500
            Loop Until modUtil.FindRunningProcess(AVSLoaderPathName) = 0 And Dir(TempPath & "\AVSInfo.txt") <> ""
        End If
    End If
    DoEvents
    modUtil.KillRunningProcess AVSLoaderPathName
    NumFile = FreeFile
    sTXT = ""
    If Dir(TempPath & "\AVSInfo.txt") <> "" Then
        Open TempPath & "\AVSInfo.txt" For Input As #NumFile
            Do Until EOF(NumFile)
                sTXT = sTXT & Input(1, #NumFile)
            Loop
        Close #NumFile
    End If
    If InStr(1, sTXT, "ASCII file generated by A2DInfo") <> 0 Then
        ReadAVSInfoS = True
        NumFile = FreeFile
        Open MediaPathName For Input As #NumFile
            Do Until EOF(NumFile)
                StrMedia = StrMedia & Input(1, #NumFile)
            Loop
        Close #NumFile
        With GeneralInfo
            .PathName = MediaPathName
            .Filename = Dir(MediaPathName)
            'FileExt
            'FileSize
            If bSourceAVSorD2V = False Then
                .Format = "Media"
            Else
                If LCase(Right(MediaPathName, 4)) = ".d2v" Then
                    .Format = "D2V"
                Else
                    .Format = "AVS"
                End If
            End If
            .MediaInfoVersion = "A2DInfo.avsi"
        End With
        If Load_Str(sTXT, "HasVideo") = "1" Then
            GeneralInfo.VideoTracksCount = "1"
            With VideoInfo
                .Time = Load_Str(sTXT, "VideoTime")
                If bSourceAVSorD2V = False Then
                    .Compression = "Unknown Video"
                Else
                    If LCase(Right(MediaPathName, 4)) = ".d2v" Then
                        .Compression = "DGIndex"
                    Else
                        .Compression = "AviSynth"
                    End If
                End If
                .AvgBitRate = Load_Str(StrMedia, "#VideoAvgBitRate", .AvgBitRate)
                .Width = Load_Str(sTXT, "Width")
                .Height = Load_Str(sTXT, "Height")
                If Val(.Height) > 0 Then .FrameAspectRatio = Replace(Val(.Width) / Val(.Height), ",", ".")
                .DisplayAspectRatio = Load_Str(StrMedia, "#DisplayAspectRatio", .DisplayAspectRatio)
                If .DisplayAspectRatio = "" Then .DisplayAspectRatio = .FrameAspectRatio
                If Val(.FrameAspectRatio) > 0 Then .PixelAspectRatio = Replace(Val(.DisplayAspectRatio) / Val(.FrameAspectRatio), ",", ".")
                .FrameRateMode = "CFR"
                .FPS = Replace(CStr(Round(Val(Load_Str(sTXT, "Framerate")), 3)), ",", ".")
                .FrameCount = Load_Str(sTXT, "Framecount")
                .ScanType = Load_Str(StrMedia, "#ScanType", .ScanType)
                .ScanOrder = Load_Str(StrMedia, "#ScanOrder", .ScanOrder)
                If .Compression = "" Then
                    ReadAVSInfoS = False
                    If bErrDisplay = True Then MsgBox "Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot detect Video Stream.", vbExclamation + vbOKOnly, App.Title & " (ReadAVSInfoS)"
                End If
            End With
        End If
        If Load_Str(sTXT, "HasAudio") = "1" Then
            GeneralInfo.AudioTracksCount = "1"
            With AudioInfo
                .Time(0) = Load_Str(sTXT, "AudioTime")
                .Compression(0) = IIf(bSourceAVSorD2V = True, "AviSynth", "Unknown Audio")
                .AvgBitRate(0) = Load_Str(StrMedia, "#AudioAvgBitRate", .AvgBitRate(0))
                .BitRateMode(0) = "CBR"
                .Channels(0) = Load_Str(sTXT, "AudioChannels")
                .SampleRate(0) = Load_Str(sTXT, "AudioRate")
                .Resolution(0) = Load_Str(sTXT, "AudioBits")
                .Delay(0) = ""
                If .Compression(0) = "" Then
                    ReadAVSInfoS = False
                    If bErrDisplay = True Then MsgBox "Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot detect Audio Stream.", vbExclamation + vbOKOnly, App.Title & " (ReadAVSInfoS)"
                End If
            End With
        End If
        With GeneralInfo
            If AudioInfo.Time(0) <> "" Then .Time = AudioInfo.Time(0)
            If VideoInfo.Time <> "" Then .Time = VideoInfo.Time
            If Val(.Time) <= 0 Then
                ReadAVSInfoS = False
                If bErrDisplay = True Then
                    If MsgBox("Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot detect Duration." & vbCrLf & vbCrLf & "Do you want to insert Duration manually?", vbExclamation + vbYesNo, App.Title & " (AVSMeter.exe)") = vbYes Then
                        Do
                            .Time = InputBox("Insert Duration [ms]:" & vbCrLf & vbCrLf & "(1 hour is 3600000 ms)", App.Title & " (AVSMeter.exe)", "5400000")
                            If Val(.Time) > 0 Then
                                VideoInfo.Time = .Time
                                AudioInfo.Time(0) = .Time
                                ReadAVSInfoS = True
                            ElseIf .Time <> "" Then
                                MsgBox "Warning! PlayTime format not valid.", vbCritical, App.Title & " (ReadAVSInfoS)"
                            End If
                        Loop Until ReadAVSInfoS = True Or Val(.Time) > 0
                    End If
                End If
            End If
        End With
    Else
        ReadAVSInfoS = False
        If bErrDisplay = True Then MsgBox "Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot find '" & TempPath & "\AVSInfo.txt' (Timeout " & TimeOut & " seconds).", vbExclamation + vbOKOnly, App.Title & " (ReadAVSInfoS)"
    End If

    GoTo Exit_Handling

Err_Handling:
If bErrDisplay = True Then MsgBox "Error " & Err.Number & vbCrLf & vbCrLf & Err.Description, vbCritical, App.Title & " (ReadAVSInfoS)"
ReadAVSInfoS = False
'Resume

Exit_Handling:
If ReadAVSInfoS = False And bErrDisplay = True Then
    MsgBox "Error reading '" & MediaPathName & "'." & vbCrLf & vbCrLf & "Cannot read Media.", vbExclamation + vbOKOnly, App.Title & " (ReadAVSInfoS)"
End If
If Dir(TempPath & "\AVSInfo.bat") <> "" Then Kill TempPath & "\AVSInfo.bat"
If Dir(TempPath & "\AVSInfo.avs") <> "" Then Kill TempPath & "\AVSInfo.avs"
If Dir(TempPath & "\AVSInfo.txt") <> "" Then Kill TempPath & "\AVSInfo.txt"
If Dir(TempPath & "\AviSynthD.avs") <> "" Then Kill TempPath & "\AviSynthD.avs"
Screen.MousePointer = vbDefault

End Function


' Erase all class properties
Public Sub Clear()

    Dim GeneralInfoNull As GeneralMediaInfoType
    Dim VideoInfoNull As VideoMediaInfoType
    Dim AudioInfoNull As AudioMediaInfoType
    Dim TextInfoNull As TextMediaInfoType
    Dim ChaptersInfoNull As ChaptersMediaInfoType
    
    GeneralInfo = GeneralInfoNull
    VideoInfo = VideoInfoNull
    If Val(AudioTracksCount) > 0 Then
        AudioInfo = AudioInfoNull
    End If
    If Val(TextTracksCount) > 0 Then
        TextInfo = TextInfoNull
    End If
    ChaptersInfo = ChaptersInfoNull
    
End Sub

Private Function Load_Str(Str As String, Object As String, Optional ByVal Default As String) As String

    ' Get string object (Object) from string (Str). If no Object is found, Default is returned
    
    Dim Inizio As Integer
    Dim Fine As Integer

    On Error GoTo Err_Handling
        
    If InStr(1, Str, Object, vbTextCompare) <> 0 Then
        Inizio = InStr(1, Str, Object, vbTextCompare) + Len(Object) + 2
        Fine = InStr(Inizio, Str, Chr(13), vbTextCompare)
        Load_Str = Mid(Str, Inizio, Fine - Inizio)
    End If
    If Load_Str = "" Then
        Load_Str = Default
    Else
        Do
            If Left(Load_Str, 1) = " " Then
                Load_Str = Right(Load_Str, Len(Load_Str) - 1)
            ElseIf Right(Load_Str, 1) = " " Then
                Load_Str = Left(Load_Str, Len(Load_Str) - 1)
            End If
        Loop Until Left(Load_Str, 1) <> " " And Right(Load_Str, 1) <> " "
    End If
    
    Exit Function

Err_Handling:
Load_Str = Default

End Function

Public Property Get MediaInfoVersion() As String

    MediaInfoVersion = GeneralInfo.MediaInfoVersion
    
End Property

Public Property Get PathName() As String

    PathName = GeneralInfo.PathName
    
End Property

Public Property Get Filename() As String

    Filename = GeneralInfo.Filename
    
End Property

Public Property Get FileExt() As String

    FileExt = GeneralInfo.FileExt
    
End Property

Public Property Get FileSize() As String

    FileSize = GeneralInfo.FileSize
    
End Property

Public Property Get Format() As String

    Format = GeneralInfo.Format
    
End Property

Public Property Get VideoTracksCount() As String

    VideoTracksCount = GeneralInfo.VideoTracksCount
    
End Property

Public Property Get AudioTracksCount() As String

    AudioTracksCount = GeneralInfo.AudioTracksCount
    
End Property

Public Property Get TextTracksCount() As String

    TextTracksCount = GeneralInfo.TextTracksCount
    
End Property

Public Property Get Time() As String

    Time = GeneralInfo.Time
    
End Property

Public Property Get VideoTime() As String

    VideoTime = VideoInfo.Time
    
End Property

Public Property Get VideoID() As String

    VideoID = VideoInfo.ID
    
End Property

Public Property Get VideoStreamOrder() As String

    VideoStreamOrder = VideoInfo.StreamOrder
    
End Property

Public Property Get VideoCompression() As String

    VideoCompression = VideoInfo.Compression
    
End Property

Public Property Get VideoBitRateMode() As String

    VideoBitRateMode = VideoInfo.BitRateMode
    
End Property

Public Property Get VideoAvgBitRate() As String

    VideoAvgBitRate = VideoInfo.AvgBitRate
    
End Property

Public Property Get VideoMinBitRate() As String

    VideoMinBitRate = VideoInfo.MinBitRate
    
End Property

Public Property Get VideoMaxBitRate() As String

    VideoMaxBitRate = VideoInfo.MaxBitRate
    
End Property

Public Property Get VideoWidth() As String

    VideoWidth = VideoInfo.Width
    
End Property

Public Property Get VideoHeight() As String

    VideoHeight = VideoInfo.Height
    
End Property

Public Property Get VideoDAR() As String

    VideoDAR = VideoInfo.DisplayAspectRatio
    
End Property

Public Property Get VideoPAR() As String

    VideoPAR = VideoInfo.PixelAspectRatio
    
End Property

Public Property Get VideoFAR() As String

    VideoFAR = VideoInfo.FrameAspectRatio

End Property

Public Property Get VideoStandard() As String

    VideoStandard = VideoInfo.Standard
    
End Property

Public Property Get VideoFrameRateMode() As String

    VideoFrameRateMode = VideoInfo.FrameRateMode
    
End Property

Public Property Get VideoFPS() As String

    VideoFPS = VideoInfo.FPS
    
End Property

Public Property Get VideoFrameCount() As String

    VideoFrameCount = VideoInfo.FrameCount
    
End Property

Public Property Get VideoScanType() As String

    VideoScanType = VideoInfo.ScanType
    
End Property

Public Property Get VideoScanOrder() As String

    VideoScanOrder = VideoInfo.ScanOrder
    
End Property

Public Property Get VideoColorSpace() As String

    VideoColorSpace = VideoInfo.ColorSpace
    
End Property

Public Property Get VideoColorCoefficients() As String

    VideoColorCoefficients = VideoInfo.ColorCoefficients
    
End Property

Public Property Get AudioID(AudioTrack As Integer) As String

    AudioID = AudioInfo.ID(AudioTrack)
    
End Property

Public Property Get AudioStreamOrder(AudioTrack As Integer) As String

    AudioStreamOrder = AudioInfo.StreamOrder(AudioTrack)
    
End Property

Public Property Get AudioTime(AudioTrack As Integer) As String

    AudioTime = AudioInfo.Time(AudioTrack)
    
End Property

Public Property Get AudioCompression(AudioTrack As Integer) As String

    AudioCompression = AudioInfo.Compression(AudioTrack)
    
End Property

Public Property Get AudioAvgBitRate(AudioTrack As Integer) As String

    AudioAvgBitRate = AudioInfo.AvgBitRate(AudioTrack)
    
End Property

Public Property Get AudioBitRateMode(AudioTrack As Integer) As String

    AudioBitRateMode = AudioInfo.BitRateMode(AudioTrack)
    
End Property

Public Property Get AudioChannels(AudioTrack As Integer) As String

    AudioChannels = AudioInfo.Channels(AudioTrack)
    
End Property

Public Property Get AudioSampleRate(AudioTrack As Integer) As String

    AudioSampleRate = AudioInfo.SampleRate(AudioTrack)
    
End Property

Public Property Get AudioResolution(AudioTrack As Integer) As String

    AudioResolution = AudioInfo.Resolution(AudioTrack)
    
End Property

Public Property Get AudioLanguage(AudioTrack As Integer) As String

    AudioLanguage = AudioInfo.Language(AudioTrack)
    
End Property

Public Property Get AudioDelay(AudioTrack As Integer) As String

    AudioDelay = AudioInfo.Delay(AudioTrack)
    
End Property

Public Property Get TextID(TextTrack As Integer) As String

    TextID = TextInfo.ID(TextTrack)
    
End Property

Public Property Get TextStreamOrder(TextTrack As Integer) As String

    TextStreamOrder = TextInfo.StreamOrder(TextTrack)
    
End Property

Public Property Get TextFormat(TextTrack As Integer) As String

    TextFormat = TextInfo.Format(TextTrack)
    
End Property

Public Property Get TextLanguage(TextTrack As Integer) As String

    TextLanguage = TextInfo.Language(TextTrack)
    
End Property

Public Property Get TextTitle(TextTrack As Integer) As String

    TextTitle = TextInfo.Title(TextTrack)
    
End Property

Public Property Get ChaptersList() As String

    ChaptersList = ChaptersInfo.List
    
End Property

