TagLibSharp를 사용하여 powershell에서 메타데이터를 쉽게 읽는 방법

14959 단어 powershellbeginners
원드라이브에서 분기별 전화 이미지 정리 및 백업을 수행하면서 내가 사용하고 있던 the script 폴더 연도 및 월 생성이 일관되지 않다는 것을 알았습니다.

기본적으로 날짜 소스에 LastWriteTime를 사용하는 현명한 해결 방법을 수행하고 있기 때문에 의미가 있다고 생각하지만 항상 충분하지는 않습니다.

몇 시간 동안 인터넷 검색을 한 후(아직 '폭식'이 아님) 두 가지 옵션이 훌륭해 보였습니다.
  • ComObject를 사용하여 파일에서 가져온 날짜 읽기
  • TagLibSharp을 사용하여 읽기

  • ComObject를 사용하여 파일에서 가져온 날짜 읽기




      $shellObject = New-Object -ComObject Shell.Application
      $directoryObject = $shellObject.Namespace($file.Directory.FullName)
      $fileObject = $directoryObject.ParseName($file.Name)
    
      $property = 'Date taken'
      for (
        $index = 5;
        $directoryObject.GetDetailsOf($directoryObject.Items,$index) -ne $property;
        ++$index
        ) {}
    
      $dateString = $directoryObject.GetDetailsOf($fileObject,$index)
    


    나에게 문제는 [datetime]::Parse 일치, 다양한 문화 등이 있어야하더라도 다양한 형식으로 ( [datetime]::ParseExact/g 시도한 것과 상관없이 해당 날짜 문자열을 실제 DateTime 객체로 구문 분석할 수 없다는 것입니다. (단순 전송$null 포함)).

    누구든지 이 문제를 해결하는 방법에 대한 아이디어가 있으면 정말 궁금합니다.

    [TagLibSharp]를 사용하여 읽기



    여기서 저에게 까다로운 부분은 powershell에서 C# dll을 로드하는 방법을 이해하는 것이었습니다.
    nuget을 사용하여 패키지를 설치하는 경우 패키지가 설치된 위치를 파악하는 가장 쉬운 방법은 Get-Package TagLibSharp | Format-List -Property Source 를 실행하는 것입니다.

    출력은 다음과 유사해야 합니다.

    ❯ Get-Package TagLibSharp | Format-List -Property Source
    
    Source : C:\Program Files\PackageManagement\NuGet\Packages\TagLibSharp.2.2.0\TagLibSharp.2.2.0.nupkg
    


    다음 코드를 사용하여 powershell 스크립트에서 dll을 로드할 수 있다는 것을 알게 되면:

        $TagLib = "C:\Program Files\PackageManagement\NuGet\Packages\TagLibSharp.2.2.0\lib\netstandard2.0\TagLibSharp.dll"
        Add-Type -Path $TagLib
    
        [System.Reflection.Assembly]::LoadFile($TagLib)
    


    읽기 부분은 정말 쉽고 이미지의 경우 찾고자 하는 속성은 ImageTag입니다.

    $tag = [TagLib.File]::Create($file)
    $tag.ImageTag
    


    TagLibSharp를 사용하면 얻을 수 있는 몇 가지 좋은 점이 있습니다.
  • ImageTag에는 직접 사용할 수 있는 DateTime 개체가 있습니다.
  • 이미지 메타데이터에 대한 전체 액세스 권한이 있으므로 예를 들어 가장 가까운 도시 이름의 위도와 경도를 기반으로 폴더를 자동으로 생성할 수 있습니다. 흥미롭게 들릴 경우 알려주시면 업데이트된 버전을 만들어 보겠습니다.
  • 예를 들어 비디오에 대해 단순Tag으로 대체를 구현할 수 있습니다.

  • 전체 버전은 아래 및 gist에서 찾을 수 있습니다.

        $TagLib = "C:\Program Files\PackageManagement\NuGet\Packages\TagLibSharp.2.2.0\lib\netstandard2.0\TagLibSharp.dll"
        Add-Type -Path $TagLib
    
        [System.Reflection.Assembly]::LoadFile($TagLib)
    
        # Get the files which should be moved, without folders
        $files = Get-ChildItem 'X:\OneDrive\Pictures' -Recurse | Where-Object { !$_.PSIsContainer }
    
        # List Files which will be moved
        $files
    
        # Target Filder where files should be moved to. The script will automatically create a folder for the year and month.
        $targetPath = 'X:\OneDrive\Photos'
    
        foreach ($file in $files) {
          $tag = [TagLib.File]::Create($file)
    
          # Get year and Month of the file
          if ($tag.ImageTag.DateTime) {
            $year = $tag.ImageTag.DateTime.Year.ToString()
            # add 0 prefix to month
            $month = $tag.ImageTag.DateTime.Month.ToString("00")
          }
          elseif ($tag.Tag.DateTime) {
            $year = $tag.Tag.DateTime.Year.ToString()
            # add 0 prefix to month
            $month = $tag.Tag.DateTime.Month.ToString("00")
          }
          else {
            # I used LastWriteTime since this are synced files and the creation day will be the date when it was synced
            $year = $file.LastWriteTime.Year.ToString()
            # add 0 prefix to month
            $month = $file.LastWriteTime.Month.ToString("00")
          }
    
          # Out FileName, year and month
          $file.Name
          $year
          $month
    
          # Set Directory Path , change as wanted
          $Directory = $targetPath + "\" + $year + "\" + $year + "-" + $month
          # Create directory if it doesn't exists
          if (!(Test-Path $Directory)) {
            New-Item $directory -type directory
          }
    
          # Move File to new location, remove -Force if you might have files with the same name, i've used it since i knew that duplicates are ok to overwrite
          $file | Move-Item -Destination $Directory -Force
        }
    

    좋은 웹페이지 즐겨찾기