① android API Level與sdk版本對照表
API等級1: Android 1.0
API等級2: Android 1.1 Petit Four 花式小蛋糕
API等級3: Android 1.5 Cupcake 紙杯蛋糕
API等級4: Android 1.6 Donut 甜甜圈
API等級5: Android 2.0 Éclair 松餅
API等級6: Android 2.0.1 Éclair 松餅
API等級7: Android 2.1 Éclair 松餅
API等級8: Android 2.2 - 2.2.3 Froyo 凍酸奶
API等級9: Android 2.3 - 2.3.2 Gingerbread 姜餅
API等級10:Android 2.3.3-2.3.7 Gingerbread 姜餅
API等級11:Android 3.0 Honeycomb 蜂巢
API等級12:Android 3.1 Honeycomb 蜂巢
API等級13:Android 3.2 Honeycomb 蜂巢
API等級14:Android 4.0 - 4.0.2 Ice Cream Sandwich 冰激凌三明治
API等級15:Android 4.0.3 - 4.0.4 Ice Cream Sandwich 冰激凌三明治
API等級16:Android 4.1 Jelly Bean 糖豆
API等級17:Android 4.2 Jelly Bean 糖豆
API等級18:Android 4.3 Jelly Bean 糖豆
API等級19:Android 4.4 KitKat 奇巧巧克力棒
API等級20 : Android 4.4W KitKat with wearable extensions奇巧巧克力棒
API等級21:Android 5.0-5.0.2 Lollipop 棒棒糖
API等級22:Android 5.1 Lollipop 棒棒糖
API等級23:Android 6.0 MarshMallow
② Android API版本對照表及各個版本特性簡單描述
5、提供屏幕虛擬鍵盤
6、主屏幕增加音樂播放器和相框widgets
7、應用程序自動隨著手機旋轉
8、簡訊、Gmail、日暦,瀏覽器的用戶介面大幅改進,如Gmail可以批量刪除郵件
9、相機啟動速度加快,拍攝圖片可以直接上傳到Picasa
10、來電照片顯示
主要的更新如下:
1、優化硬體速度
2、 「Car Home」程序
3、支持更多的屏幕解析度
4、改良的用戶界面
5、新的瀏覽器的用戶介面和支持HTML5
6、新的聯系人名單
7、更好的白色/黑色背景比率
8、改進Google Maps3.1.2
9、支持Microsoft Exchange
10、支持內置相機閃光燈
11、支持數碼變焦
12、改進的虛擬鍵盤
13、支持藍牙2.1
14、支持動態桌面的設計
5、任務管理器可滾動,支持USB 輸入設備(鍵盤、滑鼠等)。
6、支持 Google TV、可以支持XBOX 360無線手柄
7、widget支持的變化,能更加容易的定製屏幕widget插件。
7、具有開關切換的用戶界面
8、全新的電源管理系統
9、更為輕便的主題模式
10、全新的鎖屏頁面
11、全新的時鍾界面
③ android 21 是什麼版本
android每一個系統版本都對應一個編號的,21代表安卓5.0系統,23代表安卓6.0系統。
API等級15:Android 4.0.3 - 4.0.4 Ice Cream Sandwich
API等級16:Android 4.1 Jelly Bean
API等級17:Android 4.2 Jelly Bean
API等級18:Android 4.3 Jelly Bean
API等級19:Android 4.4 KitKat
API等級20:Android 4.4W
API等級21:Android 5.0 Lollipop
API等級22:Android 5.1 Lollipop
API等級23:Android 6.0 Marshmallow
(3)androidapi16對應版本擴展閱讀:
從2009年5月開始,Android操作系統改用甜點來作為版本代號,這些版本按照從C大寫字母開始的順序來進行命名:紙杯蛋糕(Cupcake)、甜甜圈(Donut)、閃電泡芙(Éclair)、凍酸奶(Froyo)、姜餅(Gingerbread)。
蜂巢(Honeycomb)﹑冰淇淋三明治(Ice Cream Sandwich)、果凍豆(Jelly Bean)、奇巧(KitKat)、棒棒糖(Lollipop)、棉花糖(Marshmallow)、牛軋糖(Nougat)、奧利奧(Oreo )、餡餅(Pie)。
④ Android原生編解碼介面 MediaCodec 之——完全解析
MediaCodec 是Android 4.1(api 16)版本引入的編解碼介面, Developer 官網 上描述的已經很清楚了。可以配合 中文翻譯 一起看。理解更深刻。
MediaCodec的工作流程:
從上圖可以看出 MediaCodec 架構上採用了2個緩沖區隊列,非同步處理數據,並且使用了一組輸入輸出緩存。
你請求或接收到一個空的輸入緩存(input buffer),向其中填充滿數據並將它傳遞給編解碼器處理。編解碼器處理完這些數據並將處理結果輸出至一個空的輸出緩存(output buffer)中。最終,你請求或接收到一個填充了結果數據的輸出緩存(output buffer),使用完其中的數據,並將其釋放給編解碼器再次使用。
具體工作如下:
MediaCodec的基本調用流程是:
1.初始化MediaCodec,方法有兩種,分別是通過名稱和類型來創建,對應的方法為:
2.配置編碼器,設置各種編碼器參數(MediaFormat),這個類包含了比特率、幀率、關鍵幀間隔時間等。然後再調用 mMediaCodec .configure,對於 API 19 以上的系統,我們可以選擇 Surface 輸入:mMediaCodec .createInputSurface,
3.打開編碼器,獲取輸入輸出緩沖區
獲取輸入輸出緩沖區在api19 上是以上方式獲取,api21以後 可以使用直接獲取ByteBuffer
4.輸入數據,有2種方式,一種是普通輸入,一種是Surface 輸入
普通輸入又可區分為兩種情況,一種是配合MediaExtractor ,一種是取原數據;
返回一個填充了有效數據的input buffer的索引,如果沒有可用的buffer則返回-1,參數為超時時間(TIMES_OUT),單位是微秒,當timeoutUs==0時,該方法立即返回;當timeoutUs<0時,無限期地等待一個可用的input buffer,當timeoutUs>0時,
等待時間為傳入的微秒值。
上面輸入緩存的index,通過getInputBuffers()得到的是輸入緩存數組,通過index和輸入緩存數組可以得到當前請求的輸入緩存,在使用之前要clear一下,避免之前的緩存數據影響當前數據,接著就是把數據添加到輸入緩存中,並調用queueInputBuffer(...)把緩存數據入隊;
5.輸出數據
通常編碼傳輸時每個關鍵幀頭部都需要帶上編碼配置數據(PPS,SPS),但 MediaCodec 會在首次輸出時專門輸出編碼配置數據,後面的關鍵幀里是不攜帶這些數據的,所以需要我們手動做一個拼接;
6.使用完MediaCodec後釋放資源
要告知編碼器我們要結束編碼,Surface 輸入的話調用 mMediaCodec .signalEndOfInputStream,普通輸入則可以為在 queueInputBuffer 時指定 MediaCodec.BUFFER_FLAG_END_OF_STREAM 這個 flag;告知編碼器後我們就可以等到編碼器輸出的 buffer 帶著 MediaCodec.BUFFER_FLAG_END_OF_STREAM 這個 flag 了,等到之後我們調用 mMediaCodec .release 銷毀編碼器
流控就是流量控制。 為什麼要控制,就是為了在一定的限制條件下,收益最大化!
涉及到了 TCP 和視頻編碼:
對 TCP 來說就是控制單位時間內發送數據包的數據量,對編碼來說就是控制單位時間內輸出數據的數據量。
TCP 的限制條件是網路帶寬,流控就是在避免造成或者加劇網路擁塞的前提下,盡可能利用網路帶寬。帶寬夠、網路好,我們就加快速度發送數據包,出現了延遲增大、丟包之後,就放慢發包的速度(因為繼續高速發包,可能會加劇網路擁塞,反而發得更慢)。
視頻編碼的限制條件最初是解碼器的能力,碼率太高就會無法解碼,後來隨著 codec 的發展,解碼能力不再是瓶頸,限制條件變成了傳輸帶寬/文件大小,我們希望在控制數據量的前提下,畫面質量盡可能高。
一般編碼器都可以設置一個目標碼率,但編碼器的實際輸出碼率不會完全符合設置,因為在編碼過程中實際可以控制的並不是最終輸出的碼率,而是編碼過程中的一個量化參數(Quantization Parameter,QP),它和碼率並沒有固定的關系,而是取決於圖像內容。 這一點不在這里展開,感興趣的朋友可以閱讀視頻壓縮編碼和音頻壓縮編碼的基本原理。
無論是要發送的 TCP 數據包,還是要編碼的圖像,都可能出現「尖峰」,也就是短時間內出現較大的數據量。TCP 面對尖峰,可以選擇不為所動(尤其是網路已經擁塞的時候),這沒有太大的問題,但如果視頻編碼也對尖峰不為所動,那圖像質量就會大打折扣了。如果有幾幀數據量特別大,但仍要把碼率控制在原來的水平,那勢必要損失更多的信息,因此圖像失真就會更嚴重。 這種情況通常的表現是畫面出現很多小方塊,看上去像是打了馬賽克一樣,導致畫面的局部或者整體看不清楚的情況
配置時指定目標碼率和碼率控制模式:
碼率控制模式有三種:
碼率控制模式在 MediaCodecInfo.EncoderCapabilities 類中定義了三種,在 framework 層有另一套名字和它們的值一一對應:
動態調整目標碼率:
Android 流控策略選擇
下面展示使用MediaExtractor獲取數據後,用MediaMuxer重新寫成一個MP4文件的簡單栗子
⑤ Android -- 音視頻基礎知識
幀,是視頻的一個基本概念,表示一張畫面,如上面的翻頁動畫書中的一頁,就是一幀。一個視頻就是由許許多多幀組成的。
幀率,即單位時間內幀的數量,單位為:幀/秒 或fps(frames per second)。一秒內包含多少張圖片,圖片越多,畫面越順滑,過渡越自然。 幀率的一般以下幾個典型值:
24/25 fps:1秒 24/25 幀,一般的電影幀率。
30/60 fps:1秒 30/60 幀,游戲的幀率,30幀可以接受,60幀會感覺更加流暢逼真。
85 fps以上人眼基本無法察覺出來了,所以更高的幀率在視頻里沒有太大意義。
這里我們只講常用到的兩種色彩空間。
RGB的顏色模式應該是我們最熟悉的一種,在現在的電子設備中應用廣泛。通過R G B三種基礎色,可以混合出所有的顏色。
這里著重講一下YUV,這種色彩空間並不是我們熟悉的。這是一種亮度與色度分離的色彩格式。
早期的電視都是黑白的,即只有亮度值,即Y。有了彩色電視以後,加入了UV兩種色度,形成現在的YUV,也叫YCbCr。
Y:亮度,就是灰度值。除了表示亮度信號外,還含有較多的綠色通道量。
U:藍色通道與亮度的差值。
V:紅色通道與亮度的差值。
音頻數據的承載方式最常用的是 脈沖編碼調制 ,即 PCM 。
在自然界中,聲音是連續不斷的,是一種模擬信號,那怎樣才能把聲音保存下來呢?那就是把聲音數字化,即轉換為數字信號。
我們知道聲音是一種波,有自己的振幅和頻率,那麼要保存聲音,就要保存聲音在各個時間點上的振幅。
而數字信號並不能連續保存所有時間點的振幅,事實上,並不需要保存連續的信號,就可以還原到人耳可接受的聲音。
根據奈奎斯特采樣定理:為了不失真地恢復模擬信號,采樣頻率應該不小於模擬信號頻譜中最高頻率的2倍。
根據以上分析,PCM的採集步驟分為以下步驟:
采樣率,即采樣的頻率。
上面提到,采樣率要大於原聲波頻率的2倍,人耳能聽到的最高頻率為20kHz,所以為了滿足人耳的聽覺要求,采樣率至少為40kHz,通常為44.1kHz,更高的通常為48kHz。
采樣位數,涉及到上面提到的振幅量化。波形振幅在模擬信號上也是連續的樣本值,而在數字信號中,信號一般是不連續的,所以模擬信號量化以後,只能取一個近似的整數值,為了記錄這些振幅值,采樣器會採用一個固定的位數來記錄這些振幅值,通常有8位、16位、32位。
位數越多,記錄的值越准確,還原度越高。
最後就是編碼了。由於數字信號是由0,1組成的,因此,需要將幅度值轉換為一系列0和1進行存儲,也就是編碼,最後得到的數據就是數字信號:一串0和1組成的數據。
整個過程如下:
聲道數,是指支持能不同發聲(注意是不同聲音)的音響的個數。 單聲道:1個聲道
雙聲道:2個聲道
立體聲道:默認為2個聲道
立體聲道(4聲道):4個聲道
碼率,是指一個數據流中每秒鍾能通過的信息量,單位bps(bit per second)
碼率 = 采樣率 * 采樣位數 * 聲道數
這里的編碼和上面音頻中提到的編碼不是同個概念,而是指壓縮編碼。
我們知道,在計算機的世界中,一切都是0和1組成的,音頻和視頻數據也不例外。由於音視頻的數據量龐大,如果按照裸流數據存儲的話,那將需要耗費非常大的存儲空間,也不利於傳送。而音視頻中,其實包含了大量0和1的重復數據,因此可以通過一定的演算法來壓縮這些0和1的數據。
特別在視頻中,由於畫面是逐漸過渡的,因此整個視頻中,包含了大量畫面/像素的重復,這正好提供了非常大的壓縮空間。
因此,編碼可以大大減小音視頻數據的大小,讓音視頻更容易存儲和傳送。
視頻編碼格式有很多,比如H26x系列和MPEG系列的編碼,這些編碼格式都是為了適應時代發展而出現的。
其中,H26x(1/2/3/4/5)系列由ITU(International Telecommunication Union)國際電傳視訊聯盟主導
MPEG(1/2/3/4)系列由MPEG(Moving Picture Experts Group, ISO旗下的組織)主導。
當然,他們也有聯合制定的編碼標准,那就是現在主流的編碼格式H264,當然還有下一代更先進的壓縮編碼標准H265。
H264是目前最主流的視頻編碼標准,所以我們後續的文章中主要以該編碼格式為基準。
H264由ITU和MPEG共同定製,屬於MPEG-4第十部分內容。
我們已經知道,視頻是由一幀一幀畫面構成的,但是在視頻的數據中,並不是真正按照一幀一幀原始數據保存下來的(如果這樣,壓縮編碼就沒有意義了)。
H264會根據一段時間內,畫面的變化情況,選取一幀畫面作為完整編碼,下一幀只記錄與上一幀完整數據的差別,是一個動態壓縮的過程。
在H264中,三種類型的幀數據分別為
I幀:幀內編碼幀。就是一個完整幀。
P幀:前向預測編碼幀。是一個非完整幀,通過參考前面的I幀或P幀生成。
B幀:雙向預測內插編碼幀。參考前後圖像幀編碼生成。B幀依賴其前最近的一個I幀或P幀及其後最近的一個P幀。
全稱:Group of picture。指一組變化不大的視頻幀。
GOP的第一幀成為關鍵幀:IDR
IDR都是I幀,可以防止一幀解碼出錯,導致後面所有幀解碼出錯的問題。當解碼器在解碼到IDR的時候,會將之前的參考幀清空,重新開始一個新的序列,這樣,即便前面一幀解碼出現重大錯誤,也不會蔓延到後面的數據中。
DTS全稱:Decoding Time Stamp。標示讀入內存中數據流在什麼時候開始送入解碼器中進行解碼。也就是解碼順序的時間戳。
PTS全稱:Presentation Time Stamp。用於標示解碼後的視頻幀什麼時候被顯示出來。
前面我們介紹了RGB和YUV兩種圖像色彩空間。H264採用的是YUV。
YUV存儲方式分為兩大類:planar 和 packed。
planar如下:
packed如下:
上面說過,由於人眼對色度敏感度低,所以可以通過省略一些色度信息,即亮度共用一些色度信息,進而節省存儲空間。因此,planar又區分了以下幾種格式:YUV444、 YUV422、YUV420。
YUV 4:4:4采樣,每一個Y對應一組UV分量。
YUV 4:2:2采樣,每兩個Y共用一組UV分量。
YUV 4:2:0采樣,每四個Y共用一組UV分量。
其中,最常用的就是YUV420。
YUV420屬於planar存儲方式,但是又分兩種類型:
YUV420P:三平面存儲。數據組成為YYYYYYYYUUVV(如I420)或YYYYYYYYVVUU(如YV12)。
YUV420SP:兩平面存儲。分為兩種類型YYYYYYYYUVUV(如NV12)或YYYYYYYYVUVU(如NV21)
原始的PCM音頻數據也是非常大的數據量,因此也需要對其進行壓縮編碼。
和視頻編碼一樣,音頻也有許多的編碼格式,如:WAV、MP3、WMA、APE、FLAC等等,音樂發燒友應該對這些格式非常熟悉,特別是後兩種無損壓縮格式。
但是,我們今天的主角不是他們,而是另外一個叫AAC的壓縮格式。
AAC是新一代的音頻有損壓縮技術,一種高壓縮比的音頻壓縮演算法。在MP4視頻中的音頻數據,大多數時候都是採用AAC壓縮格式。
AAC格式主要分為兩種:ADIF、ADTS。
ADIF:Audio Data Interchange Format。音頻數據交換格式。這種格式的特徵是可以確定的找到這個音頻數據的開始,不需進行在音頻數據流中間開始的解碼,即它的解碼必須在明確定義的開始處進行。這種格式常用在磁碟文件中。
ADTS:Audio Data Transport Stream。音頻數據傳輸流。這種格式的特徵是它是一個有同步字的比特流,解碼可以在這個流中任何位置開始。它的特徵類似於mp3數據流格式。
ADIF數據格式:
ADTS 一幀 數據格式(中間部分,左右省略號為前後數據幀):
AAC內部結構也不再贅述,可以參考AAC 文件解析及解碼流程
細心的讀者可能已經發現,前面我們介紹的各種音視頻的編碼格式,沒有一種是我們平時使用到的視頻格式,比如:mp4、rmvb、avi、mkv、mov...
沒錯,這些我們熟悉的視頻格式,其實是包裹了音視頻編碼數據的容器,用來把以特定編碼標准編碼的視頻流和音頻流混在一起,成為一個文件。
例如:mp4支持H264、H265等視頻編碼和AAC、MP3等音頻編碼。
我們在一些播放器中會看到,有硬解碼和軟解碼兩種播放形式給我們選擇,但是我們大部分時候並不能感覺出他們的區別,對於普通用戶來說,只要能播放就行了。
那麼他們內部究竟有什麼區別呢?
在手機或者PC上,都會有CPU、GPU或者解碼器等硬體。通常,我們的計算都是在CPU上進行的,也就是我們軟體的執行晶元,而GPU主要負責畫面的顯示(是一種硬體加速)。
所謂軟解碼,就是指利用CPU的計算能力來解碼,通常如果CPU的能力不是很強的時候,一則解碼速度會比較慢,二則手機可能出現發熱現象。但是,由於使用統一的演算法,兼容性會很好。
硬解碼,指的是利用手機上專門的解碼晶元來加速解碼。通常硬解碼的解碼速度會快很多,但是由於硬解碼由各個廠家實現,質量參差不齊,非常容易出現兼容性問題。
MediaCodec 是Android 4.1(api 16)版本引入的編解碼介面,是所有想在Android上開發音視頻的開發人員繞不開的坑。
由於Android碎片化嚴重,雖然經過多年的發展,Android硬解已經有了很大改觀,但實際上各個廠家實現不同, 還是會有一些意想不到的坑。
相對於FFmpeg,Android原生硬解碼還是相對容易入門一些,所以接下來,我將會從MediaCodec入手,講解如何實現視頻的編解碼,以及引入OpenGL實現對視頻的編輯,最後才引入FFmpeg來實現軟解,算是一個比較常規的音視頻開發入門流程吧。
⑥ 出現No minsdk(API 16)>device sdk(api 1)怎麼辦不兼容,手機5.0版本的
不會有問題的,由於andrid系統是向下兼容的,也就是說,高版本的SDK會兼容低版本的SDK。
舉例說明:
1. 新建一個 Android Project (HelloAndroid), 指定為 Android 2.2 版本,對應的 minSdkVersion 填8,finish;
2. 此時我們運行 HelloAndroid ,會運行一個 2.2 版本的模擬器。
3. 假若現在去 AndroidManifest.xml 文件 中修改 android:minSdkVersion=7,再次運行,那麼會在已經打開的 2.2 模擬器上運行。因為 Android API 都是向後兼容的,所以系統在編譯時,這個 Project 是利用 2.1 版本來編譯的,但也可以在 2.2 模擬器上運行;若先把 2.2 模擬器關閉,再運行 HelloAndroid 這個Project 的話,那麼會新建一個 API Level=7 的 模擬器來運行這個程序(也就是 2.1模擬器)。
4. 假若修改 android:minSdkVersion=10, 那麼無論是否打開了 2.2 版本的模擬器,都會報錯:
ERROR: Application requires API version 10. Device API version is 8 (Android 2.2).
Launch canceled。
⑦ Android各個版本的介紹
前言:筆者在面試的過程中,已經被問過不下三次,因此在這里分析一下。可能不夠詳細,請各位大佬多多包涵。
一、 版本對應的API 級別
API 級別:是對 Android 平台版本提供的框架 API 修訂版進行唯一標識的整數值。
1 ,Android 4.4 API 級別是19;
2,Android 5.0 API 級別:21;
3,Android 5.1 API 級別:22;
4,Android 6.0 API 級別:23;
5,Android 7.0 API 級別:24;
6,Android 7.1 API 級別:25;
7,Android 8.0 API 級別:26;
8,Android 8.1 API 級別:27;
9,Android 9 API 級別:28;
10,Android 10 API 級別:29;
二、版本變更
註:只舉一些常見的。
Android 4.4
1,文件的讀寫許可權,長期對文件進行讀寫;
2,增加了webview組件;
3,列印框架,通過 WLAN、藍牙或其他服務連接的列印機;
4,簡訊內容的提供,允許應用讀寫設備的簡訊和彩信;
5,NFC讀取
6,沉浸式
7,透明系統狀態欄
8,虛擬機的改變
Android 5.0
1,webview更新,增加了安全性和穩定性
2,錄屏功能
3,camera2
4,多個網路連接
5,藍牙低功耗
6,NFC增強
7,ART運行時取代了Dalvik成為平台默認設置
8,浮動窗口
Android 6.0
1,指紋身份認證
2,藍牙觸控筆並且改進藍牙低功耗
3,4K顯示
4,低功耗模式
5,USB連接授權與其他設備連接
6,APK驗證更為嚴格
Android 7.0
1,增強了低功耗模式,可以監聽到用戶的行為
2,屏幕縮放
3,快速安裝app
4,來電過濾
Android 8.0
1,自適應啟動圖標
2,增加了webview的安全性和穩定性
3,多顯示器支持,可以一邊聊天一邊看視頻
4,網路連接和 HTTP(S) 連接
5,藍牙,兼容藍牙5.0版本超過位元組約60的限制
Android 9
1,WIFI RTT可以室內定位
2,DEX 文件的 ART 提前轉換
Android 10
1,可折疊設備
2,5G網路
3,保護用戶隱私
4,安全性
5,ART 優化
⑧ Android音頻開發(三)——音頻編解碼
上一節中我們講了怎麼採集音頻並播放,由於AudioRecord採集的是PCM數據,沒有經過處理,所有播放的時候會有雜音,嘯叫等現象出現。因此處理掉這些不需要的數據就是本節的內容,編碼與解碼。
Android官方提供給我們的用於編解碼的類是 MediaCodec ,它是android 4.1(API 16)才引入的,所以只能工作於andorid4.1以上的手機,如果想兼容4.1以下版本的手機,只能使用第三方庫,如大名鼎鼎的 ffmpeg ,B站的 ijkplayer 等。
(1)提供了一套訪問 Android 底層多媒體模塊的介面,主要是音視頻的編解碼介面
(2)在Android上,預設的多媒體框架是基於第三方PacketVideo公司的OpenCORE來實現,OpenCORE的優點是兼顧了跨平台的移植性,而且已經過多方驗證,所以相對來說較為穩定;缺點是國語龐大復雜,需要耗費相當多的時間去維護。因此從Android 2.0開始,Google引進了較為簡潔的StageFright。Android 底層多媒體模塊採用的是 StageFright 框架,它是基於OpenMax標准實現的,任何 Android 底層編解碼模塊的實現,都必須遵循 OpenMax 標准。值得一提的是,OpenMAX是Khronos制定的API,Khronos也是OpenGL的制定者。Google 官方默認提供了一系列的軟體編解碼器:包括:OMX.google.h264.encoder,OMX.google.h264.encoder, OMX.google.aac.encoder, OMX.google.aac.decoder 等等,而硬體編解碼功能,則需要由晶元廠商依照 OpenMax 框架標准來完成,所以,一般採用不同晶元型號的手機,硬體編解碼的實現和性能是不同的
(3)Android 應用層統一由 MediaCodec API 來提供各種音視頻編解碼功能,由參數配置來決定採用何種編解碼演算法、是否採用硬體編解碼加速等等
根據android官方文檔的描述,MediaCodec的核心就是使用緩沖區隊列來操作數據,使用流程如下:
//name既是媒體文件的類型,如audio/3gpp,詳情參考MediaFormat的MIMETYPE常量
MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, …);
MediaFormat outputFormat = codec.getOutputFormat(); // option B
codec.start();
for (;;) {
////獲取可用的inputBuffer -1代表一直等待,0表示不等待 建議-1,避免丟幀
int inputBufferId = codec.dequeueInputBuffer(-1);
if (inputBufferId >= 0) {
ByteBuffer inputBuffer = codec.getInputBuffer(…);
// fill inputBuffer with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
//執行上面的操作後就把待編解碼的數據存入了輸入緩沖區,然後下一步就是操作然後把編解碼的數據存入輸出緩沖區
int outputBufferId = codec.dequeueOutputBuffer(…);
if (outputBufferId >= 0) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
// bufferFormat is identical to outputFormat
// outputBuffer is ready to be processed or rendered.
…
codec.releaseOutputBuffer(outputBufferId, …);
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
outputFormat = codec.getOutputFormat(); // option B
}
}
codec.stop();
codec.release();
MediaCodec codec = MediaCodec.createByCodecName(name);
MediaFormat mOutputFormat; // member variable
codec.setCallback(new MediaCodec.Callback() {
@Override
void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
// fill inputBuffer with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
@Override
void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, …) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
// bufferFormat is equivalent to mOutputFormat
// outputBuffer is ready to be processed or rendered.
…
codec.releaseOutputBuffer(outputBufferId, …);
}
@Override
void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
mOutputFormat = format; // option B
}
@Override
void onError(…) {
…
}
});
codec.configure(format, …);
mOutputFormat = codec.getOutputFormat(); // option B
codec.start();
// wait for processing to complete
codec.stop();
codec.release();
MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, …);
codec.start();
//API的區別在這里
ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffers = codec.getOutputBuffers();
for (;;) {
int inputBufferId = codec.dequeueInputBuffer(…);
if (inputBufferId >= 0) {
// fill inputBuffers[inputBufferId] with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
int outputBufferId = codec.dequeueOutputBuffer(…);
if (outputBufferId >= 0) {
// outputBuffers[outputBufferId] is ready to be processed or rendered.
…
codec.releaseOutputBuffer(outputBufferId, …);
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = codec.getOutputBuffers();
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
MediaFormat format = codec.getOutputFormat();
}
}
codec.stop();
codec.release();
⑨ 如何查看Android APP能夠運行的最低系統版本
使用Android自帶工具 aapt 即可,以Windows平台為例。
首先進入Android SDK安裝目錄,
運行命令 aapt ,
然後用記事本之類的軟體(這里使用 Notepad++ )打開剛剛生成的文件 wexin_740_sdk_v.txt ,搜索關鍵字 minSdkVersion ,如圖 1-1。
可以看到 minSdkVersion 的值是 0xf(十六進制),即 API 級別為 15(十進制)。參照圖 1-2,可以知道對應的 Android 平台版本為 Android 4.0.3、4.0.4 ,也就是說該APP能夠運行的最低系統版本為 Android 4.0.3 。
PS. API 級別(API LEVEL)是一個對 Android 平台版本提供的框架 API 修訂版進行唯一標識的整數值。可以認為API 級別是內部可見的(用戶不關心),而 Android 平台的版本提供了新特性給用戶,是外部可見的(用戶關心)。
Android 平台版本與API級別的最新對應關系可以查看以下網址:
https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels
⑩ Android開發環境搭建:jdk版本為1.7,sdk 版本選擇哪個合適
現在android開發,都是使用android studio這個官方提供的IDE,它有自帶的jdk的,目前官方默認自帶的jdk版本是1.7的,存儲在你的android studio安裝目錄下的jre目錄,你可以在android studio操作界面 File-->Project Structure 打開操作界面,SDK Location就能看到JDK location了,也可以在這里進行修改。
其實使用jdk1.7 和1.8的區別,僅僅在於你的java代碼編寫方面,1.8的版本,支持一些更簡潔的語法表達式,從某種意義上來說,這只是程序語言的進化而已。就好比最早的程序,使用10101010,但實現一個功能,可能需要寫N多的101010,於是出了編程語言,比如C,C++,用幾行英文單詞來釋義,就大大減少了工作量,然後在c++的基礎上,誕生了java,剔除了繁雜的指針問題,再到現在主流的python,以前c++,java代碼10行才能實現的功能,python可能只需要1-2行代碼就可以實現了,這就是編程語言的進化
對應的sdk版本,sdk,其實指的是android操作系統的版本,從最早的1.0beta版本到現在的9.0版本,有相當多的變化,目前市面上90%以上的android手機,操作系統都在4.x以上,也就是說,你的程序支持最低的版本,在API 16以上,即可以兼容幾乎所有的手機,而target版本,設定在API 25,26即可,最新的API 28,對應的操作系統也就是android9.0,目前還在測試階段,2018-07-02發布的,不建議把target設置為最新版本