捐血一袋救人一命

江蘇拙政園

江蘇 拙政園

全家福

日本 和歌山城

賞楓之旅

千燈 夕照

水鄉千燈

蘆洲 微風運河

破曉時分

2020年12月3日 星期四

使用 PowerShell 對文字進行Escape編碼、Unescape解碼

 這個編碼解碼結果,與 JavaScript Escape() Unescape() 相同

 

$Original = 'Instead of going back to business as usual, Uber is taking this moment as an opportunity to reduce our environmental impact.The company said in a press release.[p]Uber 在新聞稿中表示:「Uber並沒有像往常一樣重返市場,而是以此為契機,減少對環境的影響。」'

$Encode = ""

$Alphabet = @(42,43,45,46,47,48,49,50,51,52,53,54,55,56,57,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,95,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122)

$Symbol = @(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,44,58,59,60,61,62,63,91,92,93,94,96,123,124,125,126,127)

# 編碼文字

for($i = 0; $i -lt $Original.Length; $i++){

    If($([int]$($Original[$i])) -in $Alphabet){

        $Encode += $Original[$i]

    }ElseIf($([int]$($Original[$i])) -in $Symbol){

        $Encode += [System.String]::Format("%{0:X2}", [int]$Original[$i])

    }Else{

        $Encode += [System.String]::Format("%u{0:X4}", [int]$Original[$i])

    }

}

Write-host $Encode

Write-Host "`r`n"

# 還原文字

Add-Type -AssemblyName System.Web

[System.Web.HttpUtility]::UrlDecode($Encode)

使用 PowerShell 讀取 GMail 摘要 RSS

使用 PowerShell 讀取 GMail 信箱資訊,需要先設定應用程式密碼,包括使用 Outlook或是使用Windows 10內建的 Mail 程式收發郵件。

 或是想要讓事物機把掃描產生的圖檔,以電子郵件寄出,也需要設定應用程式密碼。

紅字部分,請自行更換成適當的資訊喔

Clear-Host

# 讀取 GMail Samples

$webclient = new-object System.Net.WebClient

 

# 這裡輸入的密碼,是 Application Password (應用程式密碼)

# 如何產生 Application Password (應用程式密碼)

# https://support.google.com/mail/answer/185833?hl=tw

$webclient.Credentials = new-object System.Net.NetworkCredential ("my@email.address", "MyApplicationPassword")

 之前使用 .DownloadString Method,會發現中文字都被破壞掉,所以改用 .DownloadData

# 下載 RSS,這裡得到的是一堆十進位數字的陣列,Unicode 文字是三組大於12710進位數字

$xml= $webclient.DownloadData("https://mail.google.com/mail/feed/atom")

 


 所以,接下來就是要將變數 $xml 的資訊轉換成文字(包含 Unicode)

$s = ""

For($l=0;$l -lt $xml.Count; $l++){

    If($xml[$l] -gt 127){ # 當數值大於 127,表示是 Unicode,所以轉換成16進位格式字串

        $s += "%" + $xml[$l].ToString('x2')

    }Else{ # 小於等於 127 ,就直接轉成 Ascii 字元

        $s += [char]$xml[$l]

    }

}

# Unicode 編碼進行解碼,還原成中文字

$xml = ([URI]::UnescapeDataString($s))


 

這樣 $xml 就變成 XML 格式的字串

# 輸出成 XML 檔案

$xml | Out-File -FilePath "D:\test.xml" -Encoding utf8

 

接下來要解析 XML內容,分欄顯示

# 雖然字串是 XML 格式,但不代表變數是 XML 型態,所以要進行轉換型態

$xml = [xml]$xml

 

# 設定 Format-Table 要輸出的格式

$format= @{Expression={$_.author.name};Label="Name"},

         @{Expression={"|"};Label="|"},

         @{Expression={$_.author.email};Label="E-Mail"},

         @{Expression={"|"};Label="|"},

         @{Expression={$_.title};Label="Title"},

         @{Expression={"|"};Label="|"},

         #@{Expression={$_.link|Select 'href'};Label="Link"},

         # 當你使用瀏覽器開啟 Link 的連結,就會直接讀取該郵件

         @{Expression={$_.link|Select-XML -XPath "@href"};Label="Link"},

         @{Expression={"|"};Label="|"},

         @{Expression={$_.summary};Label="summary"}

# 輸出成 Table ,缺點是過長的欄位資訊就不會出現

$xml.feed.entry | format-table $format

 


 

再來就是將 XML 內容,轉換成簡單的 HTML 檔案

# 所以底下將 XML 資訊轉換成 HTML 表格

$mail = @()

$xml.feed.entry | ForEach {

    $hash = @{

        "name" = $_.author.name

        "email" = $_.author.email

        "title" = $_.title

        "link" = ($_.link|Select-XML -XPath "@href")

        "summary" = $_.summary

    }

    $Line = New-Object -TypeName PSObject -Property $Hash

    $mail += $Line

}

$mail | ConvertTo-Html | Out-File -FilePath "D:\testxml.html" -Encoding oem

 


 

 

 

 

2020年12月2日 星期三

使用PowerShell 呼叫 ffmpeg,將串流影片合併起來,並轉換成 MP4 格式

 串流影片,就是將原始影片切分成多個小影片 *.ts,然後將多個小影片寫在一個清單檔案 *.m3u8檔案

 

當你辛苦下載了每個 .ts 影片,想要合併所有檔案,以便管理,可以使用ffmpeg來處理。

合併所有 .ts 檔案之後,要再轉換成普遍的mp4格式,也還是使用ffmpeg 來處理。

 

紅字部分,請自行評估環境修改

# 要讓產生的字串帶有雙引號括起來,是因為路徑有可能包含空白

# 如果不用雙引號括起來,後面程式會發生錯誤

$ffmpeg = """C:\Users\User\Desktop\ffmpeg-4.1.4-win64-static\bin\ffmpeg.exe"""

# 目錄不要用中文,ffmpeg 會不認得

$Root = "D:\[tts 影片存放的目錄路徑]"

If(Test-Path -Path "$Root\list.txt"){

    Remove-Item -Path "$Root\list.txt"

}

# 輸出檔案格式一定要是 utf8 (with no BOM),不然 ffmpeg 會找不到檔案

Get-ChildItem -Path $Root -Filter *.ts | Sort-Object -Property Name | ForEach{

    "file '$Root\$_'" | Out-File -FilePath "$Root\list.txt" -Append -Encoding oem

}

Write-Host "Combine Files.... Please Wait"

# 如果有設定路徑,就需要加 -safe 0 參數

$CombineArgu = "-f concat -safe 0 -i ""{0}\list.txt"" -c copy ""{0}\Combine.ts""" -f $Root

Write-Host "$ffmpeg $CombineArgu" -ForegroundColor Red

Start-Process -FilePath $ffmpeg -ArgumentList $CombineArgu -Wait -WindowStyle Normal -WorkingDirectory $Root

 

Write-Host "Convert Files.... Please Wait"

$ConvertArgu = "-i ""{0}\Combine.ts"" -acodec copy -vcodec copy ""{0}\Combine.mp4""" -f $Root

Write-Host "$ffmpeg $ConvertArgu" -ForegroundColor Red

Start-Process -FilePath $ffmpeg -ArgumentList $ConvertArgu -Wait -WindowStyle Hidden -WorkingDirectory $Root

 

2020年12月1日 星期二

用 Powershell 使用 Google Cloud Text to Speech API 服務

程式主要有兩個部分

1. 驗證(擇一)

使用 Service Account 方法

GCP Console設定服務帳號之後,產生金鑰檔,並下載金鑰檔

使用 API Key 方法

設定可使用 API Key 的 IP清單,以及可使用的 API服務項目

2. 傳送文字設定資料,並取得音效資料進行處理

 

Google Cloud Text to Speech API 服務是要收費的,所以需要經過驗證

使用 Service Account

# 載入 Google Cloud SDK 的 GoogleCloud Module for PowerShell
Import-Module GoogleCloud
# 設定 GAC 環境變數,指定服務金鑰檔案路徑
$env:GOOGLE_APPLICATION_CREDENTIALS = "D:\完整金鑰路徑檔名.json"
# 讀取金鑰後產生隨機的認證碼
$gauth = gcloud auth application-default print-access-token
# 將認證碼加到 header hashtable
$headers = @{"Authorization", "Bearer $gauth"}
$url = "https://texttospeech.googleapis.com/v1/text:synthesize" 
# ContentType 指定說明傳輸的資料格式是 JSON,編碼是 utf-8
$response = Invoke-RestMethod -ContentType 'application/json;charset=utf-8' -headers $headers -Uri $url -Method Post -body $JSON

使用 API Key

# 就是在 API 網址後面增加 Key參數

$url = "https://texttospeech.googleapis.com/v1/text:synthesize?key=你的金鑰字串"

# ContentType 指定說明傳輸的資料格式是 JSON,編碼是 utf-8

$response = Invoke-RestMethod -ContentType 'application/json;charset=utf-8' -headers $headers -Uri $url -Method Post -body $JSON

使用 API Key 程式會簡單很多,而且不用安裝 Google Cloud Library or Cloud SDK等
但是要記得設定允許使用此金鑰的 IP及服務,以確保資訊安全

 

接下來就是將文字及設定資訊傳送給Google Cloud Text to Speech API

格式一定要照規矩來,不然API會回覆錯誤

$content = "你想要讓 Google Text to Speech 唸出來的文字"

$AudioEncoding = "MP3"

$LanguageCode = "cmn-TW"

$VoiceName = "$LanguageCode-Wavenet-A"

$Effect="large-home-entertainment-class-device"

 

$JSON = @{

    audioConfig = @{

        audioEncoding = $AudioEncoding;

        effectsProfileId = $Effect;

        pitch = 0;

        speakingRate = 0.9;  # speakingRate = 0.25 ~ 4.0

        volume_gain_db = +6;  # volume_gain_db = -96.0 ~ 16.0

    };

    input = @{

    };

    voice = @{

        languageCode = $LanguageCode;

        name = $VoiceName;

    }

}

 

# 如果 Content 不是使用 SSML XML 格式, input 裡的 key 就必須使用 text

# 如果 Content 使用 SSML XML 格式, input 裡的 key 就必須使用 ssml

# 所以用程式來判斷 key 是要用 text or ssml

If($content -match [regex]"^\<speak\>" -AND $content -match [regex]"\<\/speak\>$"){

    $body.input.Add("ssml",$content)

}Else{

    $body.input.Add("text", $content)

}

 

$JSON = ConvertTo-Json ($JSON)

 

Try{

    # Content Type 除了要告知是 JSON 資料之外,還要加上 charset=utf-8,不然只會唸中文字串中的數字

    $response = Invoke-RestMethod -ContentType 'application/json;charset=utf-8' -headers $headers -Uri $target -Method Post -body $JSON

    # 回傳的 Audio Data 是 Base64 編碼的

    $base64Audio = $response.audioContent

 

# 讀取系統環境變數,取得桌面路徑

$Dest = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::Desktop)

 

    # 在桌面產生 PlayTTS.html 網頁檔案(語音資料以 Data URI  方式內嵌在網頁裡)

    "<html><head><title>Providing HTML5 audio with a base64 encoded Data URI as source</title><meta charset='utf-8'></head><body><h1>Providing HTML5 audio with a base64 encoded Data URI as source</h1><audio controls='' src='data:audio/ogg;base64,{0}'></audio></body></html>" -f $base64Audio | Out-File -FilePath "$Dest\PlayTTS.html" -Encoding oem

 

    # 使用系統預設關聯,呼叫預設瀏覽器開啟網頁檔案,不需要任何外掛JS,即可播放

    & "$Dest\PlayTTS.html"

 

    # 將 Base64 Audio Data 存成文字檔

$base64Audio | Out-File -FilePath "./google.txt" -Encoding ascii -Force

 

# 設定音效檔檔名

$convertedFileName = 'PlayTTS-{0}.mp3' -f (get-date -f yyyy-MM-dd-hh-mm-ss)

 

# 呼叫 Windows 內建 certutil.exe 將 Base64 編碼檔案解碼,檔案輸出到桌面

certutil -decode google.txt "$Dest\$convertedFileName"

 

# 開啟檔案總管,並選取輸出的音效檔

Start-Process -FilePath "$($env:WinDir)\explorer.exe" -ArgumentList "/select, $Dest\$convertedFileName"

 

}Catch {

    # 如果 Request 發生錯誤,就印出錯誤碼

    Write-Host "StatusCode:" $_.Exception.Response.StatusCode.value__

    Write-Host "StatusDescription:" $_.Exception.Response.StatusDescription

}

 

audioConfig 參考資料

SSML 參考資料

2020年11月23日 星期一

使用 PowerShell 呼叫 ffmpeg,將多個 .ts 檔案合併,並轉換成 mp4 影片

使用 PowerShell 呼叫 ffmpeg,將多個 .ts 檔案合併,並轉換成 mp4 影片