把這個ps1 放在 mp4 旁邊
按右鍵 → 用 PowerShell 執行
如果 mp4 不能移動、改名,把 PS 窗口關掉- Add-Type -AssemblyName System.Runtime.WindowsRuntime
-
- [Windows.Storage.StorageFile , Windows.Storage , ContentType=WindowsRuntime] > $null
- [Windows.Media.Transcoding.MediaTranscoder, Windows.Media.Transcoding , ContentType=WindowsRuntime] > $null
-
- #learn from https://fleexlab.blogspot.com/2018/02/using-winrts-iasyncoperation-in.html
- Function await($WinRtTask, $ResultType = $null) {
- switch($ResultType.count){
- 0{ $TaskType = 'IAsyncAction' }
- 1{
- if ($ResultType -eq [double]){
- $TaskType = 'IAsyncActionWithProgress`1'
- }else{
- $TaskType = 'IAsyncOperation`1'
- }
- }
- 2{ $TaskType = 'IAsyncOperationWithProgress`2'}
- default {throw '$ResultType error'}
- }
-
- $asTask = [System.WindowsRuntimeSystemExtensions].GetMethods() | ?{
- $_.Name -eq 'AsTask' -and
- $TaskType -eq $_.GetParameters().ParameterType.name}
-
- if ($ResultType.count -gt 0){
- $asTask = $asTask.MakeGenericMethod($ResultType)
- }
-
- $netTask = $asTask.Invoke($null, @($WinRtTask))
- $netTask.Wait(-1) | Out-Null
- if ($TaskType -like 'IAsyncOperation*'){
- $netTask.Result
- }
- }
-
- Function mp4Trim($mp4Path, $startTime = 0, $stopTime = 0, $musicOnly = $false){
-
- $transcoder = [Windows.Media.Transcoding.MediaTranscoder]::new()
- $startTime, $stopTime = $startTime, $stopTime -replace '^\d+$','0:0:$&' -replace '^\d+:\d+$','0:$&'
- $transcoder.TrimStartTime = $startTime
- $transcoder.TrimStopTime = $stopTime
-
- $a = [Windows.Storage.StorageFile]
- $mp4 = await ($a::GetFileFromPathAsync($mp4Path)) ($a)
-
- $a = [Windows.Media.MediaProperties.MediaEncodingProfile]
- $encProfile = await $a::CreateFromFileAsync($mp4) ($a)
- $mp4SaveName = $mp4.name
-
- if ($encProfile.video -ne $null -and $musicOnly){
- $q = [Windows.Media.MediaProperties.AudioEncodingQuality]::High
- $a = [Windows.Media.MediaProperties.MediaEncodingProfile]
- $ext = ''
- switch($encProfile.Audio.Subtype){
- 'AAC'{$ext = 'm4a'}
- 'MP3'{
- $ext = 'mp3'
- # if set to $flase, something error when listening to mp3
- $transcoder.AlwaysReencode = $true
- }
- 'WMA9'{$ext = 'wma'}
- }
-
- if ($ext -ne ''){
- $musicProfile = $a::"Create$ext"($q)
- $musicProfile.Audio = $encProfile.Audio
- $encProfile = $musicProfile
- $mp4SaveName = $mp4.DisplayName + ".$ext"
- }
- }
- if ($encProfile.Audio.Subtype -eq 'WMA8'){$transcoder.AlwaysReencode = $true}
-
- $a = [Windows.Storage.StorageFolder]
- $mp4Folder = await ($mp4.GetParentAsync()) ($a)
-
- $a = [Windows.Storage.StorageFile]
- # GenerateUniqueName=0; ReplaceExisting=1; FailIfExists=2; OpenIfExists=3
- $mp4Save = await ($mp4Folder.CreateFileAsync($mp4SaveName, 0)) ($a)
-
- $a = [Windows.Media.Transcoding.PrepareTranscodeResult]
- $prepare = await ($transcoder.PrepareFileTranscodeAsync($mp4, $mp4Save, $encProfile)) ($a)
-
- if($prepare.CanTranscode){
- write-host "transcoding"
- await ($prepare.TranscodeAsync()) ([double])
- Write-Host "transcode complete"
- Write-Host 'wait 2 seconds for transcoder unlock'
- sleep 2
- }else{
- Write-Host "can't transcode"
- }
-
- }
- function mp4Property($mp4Path, $title = '', [uint32]$rating = 60, $comment = ''){
-
- $a = [Windows.Storage.StorageFile]
- $mp4 = await ($a::GetFileFromPathAsync($mp4Path)) ($a)
-
- $a = [Windows.Storage.FileProperties.VideoProperties]
- $videoP = await ($mp4.Properties.GetVideoPropertiesAsync()) ($a)
- # star 1..12 13..37 38..62 63..87 88..99
- $videoP.Rating = $rating
- await $videoP.SavePropertiesAsync()
-
- $a = [Windows.Storage.FileProperties.DocumentProperties]
- $docP = await ($mp4.Properties.GetDocumentPropertiesAsync()) ($a)
- $docP.title = $title
- $docP.Comment = $comment
- await $docP.SavePropertiesAsync()
-
- <#
-
- $a = [Windows.Storage.FileProperties.ImageProperties]
- $imgP = await ($mp4.Properties.GetImagePropertiesAsync()) ($a)
-
- $a = [Windows.Storage.FileProperties.MusicProperties]
- $musicP = await ($mp4.Properties.GetMusicPropertiesAsync()) ($a)
-
- #all properties
- $videoP, $docP, $imgP, $musicP
-
- #properties (can set)
- $videoP, $docP, $imgP, $musicP | gm 'put_*' -Force
-
- #>
-
- <#
-
- # https://docs.microsoft.com/en-us/windows/win32/properties/props
-
- $a = [System.Collections.Generic.IDictionary[string, Object]]
- [string[]]$propNames = 'System.Title', 'System.Rating', 'System.Comment'
- await $mp4.Properties.RetrievePropertiesAsync($propNames) ($a) |%{
- "{0} : {1}" -f $_.Key, $_.Value
- }
-
- $s = 'System.Collections.Generic.KeyValuePair[string,System.Object]'
- $a = [type]$s
- $arr = @(
- $a::new('System.Title', $title),
- $a::new('System.Rating', $rating),
- $a::new('System.Comment', $comment)
- ) -as [type]"$s[]"
-
- await $mp4.Properties.SavePropertiesAsync($arr)
-
- #>
- }
-
- cd -literal $PSScriptRoot
- [Environment]::CurrentDirectory = pwd
-
- $files = @(dir *.mp4, *.mp3, *.m4a, *.wmv, *.wma -file)
- if ($files.count -ne 0){
- # mp4Trim filePath startTime stopTime musicOnly
- mp4Trim $files[0] 0:20 1:50
-
- # music only
- # mp4Trim $files[0] 0:20 1:50 $true
-
- # music only & after 0:20
- # mp4Trim $files[0] 0:20 0 $true
-
- # mp4Property filePath title rating comment
- # (1 ~ 5 star) rating 1..12 13..37 38..62 63..87 88..99
- mp4Property $files[0] 'a title' 90 'a comment'
-
- }
- # When mp4 can't move or Rename , close PowerShell console
复制代码
|