PTP:
圖片傳輸協議的 縮寫,全稱為:picture transfer protocol;
PTP是最早由柯達與微軟協商制定的一種標準,符合這種標準的映像裝置在接入Windows XP系統之後可以更好地被系統和應用程式所共用,尤其在網路傳輸方面,系統可以直接存取這些裝置用於建立網路相簿時圖片的上傳、網路聊天時圖片的傳送等。
MTP:
媒體傳輸協議,是基於PTP(Picture Transfer Protocol)協議的擴充,主要用於傳輸媒體檔案,其中有價值的應用就是同步DRM檔案的license。目前支援MTP協議的只有 WMP10(Windows Media Player 10)和WMP11(Windows Media Player 11)兩個版本,WMP11加入了對Playlist和Album art的支援,在擷取媒體檔案資訊的時候GetObjectPropList代替了WMP10的GetObjectInfo命令。
MTP支援對數字音頻播放器的音樂檔案和移動媒體播放器上的電影檔案的傳輸,它是 Windows Media架構的一部分,因此與Windows Media Player緊密相關。Windows Vista內建了對MTP的支援,在Windows XP中支援MTP需要安裝Window Media Player 10或以上的版本。Mac和Linux有支援MTP的軟體包。
MTP的應用分兩種角色,一個是作為Initiator,另一個作為Responder。例如:WMP(Windows Media Player)就是Initiator,而portable media player裝置就是作為Responder。Responder都是被動的回複Initiator的命令,不會主動發命令。主要的用途是傳輸媒體檔案(Media File),並從(向)裝置關聯中繼資料,對裝置的遠端控制有可選的額外支援,讀取和設定裝置參數,如特別的DRM相關的受限內容裝置參數。裝置也可向主機發送事件(event)。
MTP既可以實現在USB協議上,也可以實現在TCP/IP協議上,它屬於上層的應用協議,而不關心底層傳輸協議。目前大部分裝置的應用都是基於USB協議。市場上支援MTP的裝置有Motorola的Z6, U9, E8等,還有索尼NWZ-A81X系列。總之有越來越多的裝置開始支援MTP。微軟官方有一個 PlaysForSure的認證,如果你的裝置通過了微軟的這個測試,就會授權給你一個PlaysForSure的標誌。
MTP in Android
MTP的全稱是Media Transfer Protocol(媒體傳輸協議),它是微軟公司提出的一套媒體檔案傳輸協議。Android從3.0開始支援MTP。不過,在今天的智能手機領域內,Google和微軟是一對冤家,為什麼Android中會使用MTP呢。請看下文。 一 背景知識介紹
筆者相信《程式員》雜誌的絕大多數讀者或多或少都使用過MTP。因為早在智能手機普及前,數位相機和MP3播放器等都使用了MTP的前身PTP(Picture Transfer Protocol)進行媒體檔案傳輸。那時,只要通過USB資料線把它們串連上Windows作業系統,就能在“我的電腦“中見到這些裝置了。此後,使用者可以把它們當做隨身碟一樣使用,例如對其進行目錄、檔案的瀏覽和拷貝等操作。
既然可以通過MTP把智慧型裝置當作隨身碟使用,那麼它和我們常用的USB大型存放區(USB Mass Storage,簡稱UMS)有何不同呢。 UMS模式下,PC操作存放裝置的粒度是裝置塊(FAT block),而非檔案系統。什麼意思。此處舉一個簡單例子。當Android手機通過UMS將sdcard掛載到PC後,PC就擁有對sdcard的絕對控制權。這樣,手機就無法同時訪問sdcard了。這種做法帶來的後果就是Camera或Music程式將因沒有外部儲存空間而提示無法進行操作(注意,有些廠商的手機對此進行過修改,使得Camera能短時間錄製一部分視頻到內部儲存空間)。這也是Android早期版本中一個很明顯的特點。另外,由於PC在操作sdcard時可能弄壞其檔案系統,這將導致sdcard重新掛載到手機後不能被識別。 如果Android手機的sdcard以MTP模式掛載到PC機上,sdcard的控制權其實還是屬於手機。只不過智能手機通過MTP協議向PC機構建了一個虛擬檔案系統。PC機操作其中的檔案時,都會通過標準MTP協議向智能手機發起請求。另外,Android把MTP功能整合在MediaProvider[1]中,其好處是PC機操作(例如拷貝或刪除等)媒體檔案時,媒體資料都會及時更新到媒體資料庫中。而UMS模式下,當sdcard掛載回手機後,Android還得花較長時間重新掃描媒體檔案以更新媒體資料庫。
MTP的好處還有很多,例如它可判斷PC機拷貝的媒體檔案是否受目標手機支援,甚至可以觸發對應的轉碼程式將其轉換成手機支援的格式。不過和UMS相比,MTP也有不足之處: 傳輸大檔案的速度較慢。 MTP不能直接修改檔案本身。只能先拷貝到本地修改,完畢後再拷貝回去。 除了Windows外,Linux和MacOS對MTP支援還不是很完善。
下面我們將介紹MTP協議。 1.1 MTP協議介紹
根據協議,MTP的使用者包括兩個部分,分別是Initiator和Responder。如圖1-1所示:
圖1-1 Initiator和Responder圖示
由圖1-1可知: Initiator:主要是指USB Host,例如PC機,筆記本等。協議規定所有MTP操作只能由Initator發起。 Responder:一般是諸如數位相機、智能手機等儲存媒體檔案的裝置。Responder在MTP中的作用就是處理Initator發起的請求。同時,它還會根據自身狀態的變化發送Event以通知Initiator。
注意:後文我們將統一以PC代表Initiator,Android手機代表Responder。
與很多協議一樣,MTP也有自己的協議棧,如圖1-2所示:
圖1-2 MTP協議棧
由圖1-2可知,MTP協議棧由下到上分別是: Pyshical Layer(物理層):物理層在MTP協議中用來傳輸資料。目前有三種物理層可供MTP使用。它們分別是USB:其主要特點是傳輸檔案,同步媒體檔案時速度快,而且可以邊工作邊充電,這是目前用的最多的一種方式;IP:基於IP的MTP(簡稱MTP/IP)將通過UPnP來匹配和發現裝置。它是家用網路中是最理想的傳輸方式;Bluetooth:MTP/BT是最省電,同時也是速度最慢的一種傳輸方式,用處較少。 傳輸層:MTP中,資料轉送格式遵循PTP協議 命令層:實現了MTP協議中的各種命令。
如上文所述,MTP採用命令-應答方式來工作(Initator發送命令給Responder處理,Responser反饋處理結果),這種方式的主要特點有: 所有MTP命令均以Package(資料包)的方式在裝置兩端進行傳遞。 Initiator必須接收到前一條訊息的處理結果(不論是成功還是逾時)後,才能發送下一條訊息。
下面我們將以PC通過MTP開啟一個檔案為例,按順序介紹其中涉及到幾個主要MTP命令: 當裝置第一次串連上PC後,Initiator(即PC)首先會發送一個名為GetDeviceInfo的請求以擷取裝置的資訊,這些資訊包括裝置所支援PTP版本的程度,以百分比符號表示(預設是100)、所支援的MTP命令(Operation Supported)、所支援的Event類型等。 接著PC端會發送OpenSession命令以建立一個會話,該會話一直保持到裝置從PC上斷開為止。此後所有命令(除GetDeviceInfo命令外)必須在此會話存活期間才能發送。會話在MTP協議中由SessionID來標識,它是一個32位的無符號整型,由PC選擇並傳給手機。 PC端如果要進行檔案操作的話,必須從根目錄開始定位目標檔案。由於Windows的特殊性,手機內部儲存卡在windows系統中顯示為盤符。注意,如果手機內部有兩Block Storage卡的話(如內部儲存卡和外部sd卡),Windows中會顯示為兩個盤符。PC端需要通過GetStorageIDs命令返回某個盤符對應的StorageID。在MTP中,StorageID是一個32位無符號整型,每一個StorageID代表了一個邏輯盤符。 PC端可以根據上一步的StorageID號,利用GetStorageInfo操作去擷取存放裝置的資訊,例如剩餘儲存空間、檔案系統類型、存取權限等。 接著,PC就會通過GetObjectHandles命令來擷取此盤符下的檔案和子目錄的Object Handles(一個Object Handle代表一個檔案或目錄。該值由Responder產生並保證唯一性)。有了Object Handle,PC就可以操作這些檔案或目錄了,例如繼續通過GetObjectHandles擷取某個目錄中子檔案和子目錄的資訊。 假設現在需拷貝一個檔案到手機上,那麼PC會通過SendObjectInfo命令將檔案資訊(如檔案名稱、檔案大小)等傳遞給手機。而手機需要檢查目標目錄是否有足夠的空間和對應許可權。 如果一切正常,PC將通過SendObject把資料傳遞給手機。真正寫檔案到裝置儲存空間的則是手機中的Responder。Android實現的MTP還會在媒體檔案傳輸完畢後,將資訊更新到媒體資料庫中。 除此之外,PC還可利用SetObjectPropValue 命令來設定檔案的各種屬性值,如Audio BitRate(位元速率),Sample Rate(採樣率),Number Of Channels(聲道)等。
以上為讀者描述了MTP使用的一個簡單案例。至於其中的各種MTP命令,讀者不妨閱讀參考文獻1,即《MTP Specification v1.0.pdf》。協議對各種命令都有非常精確的描述,例如表1-1,表1-2所示為GetDeviceInfo命令,傳回值定義。其參數類型,傳遞方向都有詳細解釋(不得不說,和Linux比起來,微軟的開發/技術文檔做得相當到位)。
表1-1 GetDeviceInfo命令定義
| Operation Code |
0x1001 |
GetDeviceInfo對應命令的數字編號是0x1001 |
| Data |
DeviceInfo dataset |
手機端返回的裝置資訊資料集 |
| Data Direction |
R->I |
資料轉送方向是手機到PC |
| ResponseCode Options |
OK, Parameter_Not_Supported |
手機給PC的傳回值 |
表1-2所示為GetDeviceInfo的返回資料集的定義。
表1-2 GetDeviceInfo返回資料集的定義
| Dataset field |
Field order |
Size (bytes) |
Datatype |
Comments |
| Standard Version |
1 |
2 |
UINT16 |
手機對PTP協議的支援程度,以%表示,預設是100 |
| MTP Vendor Extension ID |
2 |
4 |
UINT32 |
手機對PTP廠商擴充協議的支援,預設是0xFFFFFFFF |
| MTP Version |
3 |
2 |
UINT16 |
手機支援的MTP標準的版本,以%表示 |
| MTP Extensions |
4 |
Variable |
String |
手機支援的MTP擴充集 |
| Functional Mode |
5 |
2 |
UINT16 |
手機允許的模式 |
| Operations Supported |
6 |
Variable |
Operation Code Array |
在當前功能模式下,手機支援的所有操作 |
| |