Google Web Speech API 語音辨識 持續收音

Google 的 web speech API 已經推出一段時間了,最近剛好有機會來試試。
Web speech API 的操作並不困難,基本上就是 var recognition = new webkitSpeechRecognition();,可以在下方參考資料中看到相關原始碼,唯獨我預設的需求是必須可持續收音,因使用者可能是在不適合任何物理碰觸的環境下操作,所以鍵盤滑鼠及觸控螢幕皆不適合在此當作 input 來源。然而 web speech API 的持續收音 recognition.continuous = true; 若發現麥克風閒置太長的話,一樣會自動停止收音,因此還是要再重新觸發 recognition.start();,所幸我就將 recognition.start(); 寫到 onend event handler,天真的以為這樣就解決問題了。

要求使用麥克風
當每次收音結束後又重新觸發開始時,就會跳出這個允許授權的視窗,而當然此時是不能收音的,可以在此範例體驗一下。

經過一番查證後,發現其實這個問題也不算問題,只是因為 chrome 要求安全性而在 http 上做出每次收音前都須要先確認允許才行,若是使用 https 的話只要允許過第一次後就再也不會詢問了,下方範例即是上方同一個範例的 https 版本。

允許之後就可以在麥克風例外狀況中看到已經預設允許的清單,在此清單中被允許的就再也不會跳出詢問視窗了,而 localhost 也是在允許範圍內,因此就可以做出很多有趣的事情了!
麥克風例外狀況

使用上的話,目前好像也沒看到什麼限制,也沒找到限制相關的文件,自己親自掛了好幾小時也還是活得好好的。

參考資料:

  1. Voice Driven Web Apps: Introduction to the Web Speech API
  2. Web Speech API Demonstration
  3. Google 語音辨識 API

Parse Server APNS(iOS) 推播通知設定

Parse 的一大方便之處,即是他提供了推播通知(push notification)的整合,使開發者可以在短時間內完成推播功能;而推播通知也已經移植到 Parse Server 版本上,步驟與先前在 Parse 上差不了多少,在這裡紀錄一下 APNS(iOS) 設定的步驟。

建立 SSL 憑證

在發送推播前必須給予 Parse Server 推播的權限,因此要先建立對應的 App ID 及 SSL 憑證。

1. 建立 Explicit App ID

如果原本就已經有建立 Explicit App ID 的話,請跳過此步驟到 2. 設定推播通知

  1. Apple Developer Member Center 登入,點選 Certificates, Identifiers & Profiles
  2. 點選左欄中 Identifiers 底下的 App IDs
  3. 點選右上角 + 的按鈕。
    建立 App ID
  4. 在 App ID Description 填上想要的名稱。
  5. 選擇 App ID Prefix,我的只有一組,好像預設就會自己選了~
  6. App ID suffix 要注意選擇 Explicit App ID,而 Bundle ID 可參考 Apple 推薦的填法或是自己偏好的格式,須注意這組之後會在 Xcode 中使用到。
    Explicit App ID
  7. 將有需要用到的服務打勾,Push Notifications 記得要打勾!其餘就看自己有沒有要用到再開啟。
    Apple Services
  8. 點選 Contiune 進行下一步,確認無誤後就可以送出了。

2. 設定推播通知

到這裡,應該已經建立好一個 Explicit App ID。

  1. 點開 App IDs 底下已建立的 App ID,再點選 Edit。
    App IDs Edit
  2. 找到 Push Notifications 項目,若沒 Enable 則將他打勾,可以在此建立 Development 跟 Production 的憑證,建議先從開發模式開始,點選 Development SSL Certificate 中底下的 Create Certificate…。
    Create Certificate
  3. 接下來他會教你怎麼做,然後要你做完再點選 Contiune,因為我英文對應中文 MAC OS 不太熟,所以在這裡也把步驟打出來了,開啟 MAC 中的「鑰匙圈存取」。
    鑰匙圈存取
  4. 點選「鑰匙圈存取」→「憑證輔助程式」→「從憑證授權要求憑證…」(蠻饒舌的)。
    從憑證授權要求憑證…
  5. 在「使用者電子郵件位址」輸入自己的 Email,「一般名稱」輸入自己想要的名稱,「CA 電子郵件位址」留白,「已將要求」選擇「儲存到硬碟」,接著點選「繼續」來產生 CSR 檔。
    憑證輔助程式
  6. 將剛剛儲存的 CSR 檔案上傳。
    Upload CSR file
  7. 下載憑證,下載完成後點選兩下此檔案,使檔案安裝到「鑰匙圈存取」中。
    Download certificate
  8. 開啟「鑰匙圈存取」,在左欄點選「我的憑證」,你可能會看到 Apple Development Push Services: 及 Apple Push Services:,這兩個分別對應了 development 憑證及 production 憑證,端看你使用哪一個。
    Apple Development Push Services: & Apple Push Services:
  9. 在要使用的憑證上點選右鍵,選擇「輸出」項目,儲存名稱依自己喜歡而定。
    Export certificate
  10. 在按儲存時會跳出密碼詢問的視窗,記得留白
    Leave it blank
  11. 最後產生的檔案,將此檔案放到 Parse Server 的目錄內。
    .p12

Parse Server 設定 APNS

延續 Parse Server 架設教學中所使用的程式碼,在 new ParseServer 中加入 push 相關的程式碼,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var api = new ParseServer({
databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
appId: process.env.APP_ID || '7c6a1d1470fed0313b5044c4eb83def0',
masterKey: process.env.MASTER_KEY || '98584a6e0a2592c274d1e4eae44b0a7b', // Add your master key here. Keep it secret!
serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse', // Don't forget to change to https if needed
liveQuery: {
classNames: ["Posts", "Comments"] // List of classes to support for query subscriptions
},
// 以下為新增部分
push: {
// 此篇未提到 Android,因此註解掉
// android: {
// senderId: '...',
// apiKey: '...'
// },
ios: {
pfx: 'pushDevelopmentCertificate.p12', // 與 index.js 目錄同層
bundleId: 'com.pushTest', // 填入先前填的 Bundle ID
production: false // false: development, true: production
}
}
});

而若需要同時使用 development 及 production 的 APNS 時,可以將設定改為這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
push: {
ios: [
{
pfx: '', // Dev PFX or P12
bundleId: '',
production: false // development
},
{
pfx: '', // Prod PFX or P12
bundleId: '',
production: true // production
}
]
}

設定 client apps

App 部分的設定與先前 Parse 的設定一樣,因此在這裡省略,可以參考 Push Configuring Clients 尋找自己需要的程式語言寫法。

測試推播通知

推播傳送的方式一樣可用 curl 或是 cloud code,唯一要注意的是傳送推播通知需要 masterKey,可以參考 Send Push Notifications。而 Parse Dashboard目前也可以傳送推播通知了,只可惜目前只可以傳而不能看傳送紀錄,下圖為 parse-dashboard 1.0.8 的畫面。
Parse Dashboard send push

疑難雜症

正常來說過沒多久就 app 就能收到推播通知,如果沒有成功的話可以新增這兩個環境變數 VERBOSE=1DEBUG=apn,若 VERBOSE=1 看不出結果再觀察 DEBUG=apn,其餘問題可能就要爬 issues 了。

筆者遇到的問題很蠢,就是所在的網路環境中 port 2195 被鎖了,因此試了半天都推播失敗 Orz,請先確定自己到 gateway.sandbox.push.apple.com:2195 (development) 及 gateway.push.apple.com:2195 (production) 是否能通~

參考資料:

  1. parse-server wiki - push
  2. PushTutorial - Push Notification Sample App
  3. Parse Dashboard

Parse Server 架設教學

在今年一月底時 Parse 突然丟下了一枚震撼彈(Moving On),隨著 Parse 服務將在一年後關閉的消息,同時也提到將會把 Parse Server open source 出來,如今兩個月過去了,釋出的 Parse Server 也趨於完善,不只提供了許多雲端服務的整合方案,連 Parse Dashboard 也在三月初時 open source 了(Introducing the Parse Server Dashboard),雖然這個 Dashboard 目前並不像 Parse 線上服務的功能一樣完整,但在短短一個月內間又多了推播(push notification)功能頁面(Push and Config come to the Parse Dashboard),可以預見未來功能會越來越完整。

單純架設 Parse Server 的難度不高,在 GitHub 有對於要在 local 架設或是部屬到其他服務上如 Heroku 的範例教學,wiki 頁面也有更完整的解說,但從這裡開始我個人認為不是個好選擇,以指令方式去帶 appId 及 masterKey 總有可能會發生什麼意外。Parse 另外提供了 parse-server-example,這個對於入門來說會比較方便。

前置環境

  • Node 4.3 以上
  • MongoDB version 2.6.X or 3.0.X
  • Python 2.x (For Windows users, 2.7.1 is the required version)

架設 Parse Server

  1. 先從 GitHub 上抓一份 parse-server-example 下來。

    1
    $ git clone https://github.com/ParsePlatform/parse-server-example.git --depth 1
  2. 將必要的模組裝上。

    1
    $ npm install
  3. index.js 中修改參數,可以選擇修改環境變數或是直接修改後面字串:

    • appId: 可填任意字串,用於識別 Parse API 的使用權限。在這裡用了 md5 來產生隨機字串。
    • masterKey: 可填任意字串,但不要公開此字串,用於覆寫權限設定。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var api = new ParseServer({
    databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
    cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
    appId: process.env.APP_ID || '7c6a1d1470fed0313b5044c4eb83def0',
    masterKey: process.env.MASTER_KEY || '98584a6e0a2592c274d1e4eae44b0a7b', // Add your master key here. Keep it secret!
    serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse', // Don't forget to change to https if needed
    liveQuery: {
    classNames: ["Posts", "Comments"] // List of classes to support for query subscriptions
    }
    });
  4. 到這裡可以先執行看看。

    1
    $ npm run start

    此時 Parse API 預設會掛在 http://localhost:1337/parse/ 下,有兩種方式可以測試是否運作正常:

    1. 直接到第五步驟,利用此包程式碼中的範例網頁來測試。
    2. curl 來測試 Parse 的 REST API 是否正常運作,X-Parse-Application-Id 需改成在 index.js 中設定的 appId
    1
    2
    3
    4
    5
    curl -X POST \
    -H "X-Parse-Application-Id: 7c6a1d1470fed0313b5044c4eb83def0" \
    -H "Content-Type: application/json" \
    -d '{"score":1337,"playerName":"Sean Plott","cheatMode":false}' \
    http://localhost:1337/parse/classes/GameScore

    若正常無誤會得到以下類似的結果:

    1
    2
    3
    4
    {
    "objectId": "CT8BWvZ8Fi",
    "createdAt": "2016-04-08T02:55:57.802Z"
    }

    取值可利用以下指令來測試,GameScore 後面需加上剛剛回傳的 objectId

    1
    2
    3
    curl -X GET \
    -H "X-Parse-Application-Id: 7c6a1d1470fed0313b5044c4eb83def0" \
    http://localhost:1337/parse/classes/GameScore/CT8BWvZ8Fi

    正常的話即可拿回上一步所傳的內容:

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "objectId": "CT8BWvZ8Fi",
    "score": 1337,
    "playerName": "Sean Plott",
    "cheatMode": false,
    "updatedAt": "2016-04-08T02:55:57.802Z",
    "createdAt": "2016-04-08T02:55:57.802Z"
    }

    詳細操作可參考 REST API Guide

  5. 在這個範例中有提供 REST API 及 Cloud Code 的測試程式碼,可以執行看看功能是否正常。
    public/assets/js/script.js 中,將 myAppId 取代成自己目前的 appId,共有兩處;接著開啟 http://localhost:1337/public/test.html 即可看到測試頁面,依序點選下方的 POST, FETCHTEST,若正確無誤的話應能看到以下結果:
    Parse Server Test
    看到這個結果就代表 REST API 及 Cloud Code 都沒有問題,下一步就看自己是不是要加推播通知的設定及 Dashboard 了!

參考資料:

  1. parse-server
  2. parse-server wiki
  3. parse-server-example
  4. parse-server issues

實作 gooey 膠粘效果

最近在試著實作 gooey 效果,看了一些介紹後知道了 gooey 的原理,本以為在實作上可以一路順風,但果然沒有這麼簡單,還好最後有找到解決方法。

先來談談 gooey 的作法,首先要先有兩層 layer,內層將物件模糊 blur,而外層處理亮度 brightness 跟對比度 contrast,接著神奇的事情就會發生了,可以參考以下範例:

See the Pen Blur vs Contrast by Chris Coyier (@chriscoyier) on CodePen.

上層是只加了模糊,可以看到因為模糊的關係,物件間的顏色互相疊加在一起;下層則是調整對比後的結果,將模糊過的結果保留重疊及原本顏色較深的部分,濾掉顏色較淺的部分,物件間的部分就因此連起來了,若是加上動畫,效果就會更好:

See the Pen Gooey Pagination by Lucas Bebber (@lbebber) on CodePen.

這樣看似已經完成了,但實際上會遇到兩個問題:

  1. 內部物件模糊掉,使用了 filter: blur(); 後,子元素無一倖免。
  2. 更改顏色,所有更改顏色都會因對比而偏移掉。

原本就是卡在這裡,不管怎麼調整都沒辦法有效的解決這兩項,後來看到了 Creative Gooey Effects 這篇才知道可以利用 fliter: url(); 配合 SVG filters 來解決這兩個問題,且用法也很簡單。此方法在 The Gooey Effect 中描述的更加清楚,包含在 feColorMatrix 中的 values 為什麼是下表也有描述,若是對他的敘述不清楚的話可以先看 SVG 研究之路 (11) - filter:feColorMatrix 稍微釐清一下。

簡單來說,若是沒有特別需求,就去調整 color matrix 中的 alpha channel (A) 跟 plus(+) 中值來得到自己想要的結果。

* R G B A +
R 1 0 0 0 0
G 0 1 0 0 0
B 0 0 1 0 0
A 0 0 0 18 -7

以下是我在測試時寫的比較:

  1. 用純 CSS 處理,背景與下一項的顏色設定相同,但呈現出 #0000FF 的藍色。

    See the Pen Rotate loading (bad with and text) by North (@ssk7833) on CodePen.

  2. 用 SVG 處理,上一版的改良,在元素中放文字將會正常顯示。

    See the Pen Gooey rotate loading (good with background and text) by North (@ssk7833) on CodePen.

  3. 將第二版的顏色稍加調整,移除 feBlend 後由於失去 SourceGraphic 的關係,文字將不會正常顯示,但此效果我更喜歡。

    See the Pen Gooey rotate loading (good with only background) by North (@ssk7833) on CodePen.

在寫上述三項測試時,自己也試過許多不同的組合,對 SVG filters 也多了許多理解,而在 gooey 相關的效果基本上就是 feGaussianBlurfeColorMatrixfeBlend 的變化所組成,未來若遇到類似需求時應該都能迎刃而解~

參考資料:

  1. Shape Blobbing in CSS
  2. 噁心黏黏球( 純 CSS )
  3. Creative Gooey Effects 底下有幾個動畫範例值得一看
  4. The Gooey Effect
  5. SVG 研究之路 (11) - filter:feColorMatrix