1. android 實時視頻採集—Camera預覽採集與顯示(平台系統camera功能理解分享)
本文之所以有必要編寫並作記錄,主要原因是因為在工作中開發出一個萬能的自定義camera預覽控制項之後,本是一個提高效率以及提供一個強大能力的控制項,但是產品並不能理解這個萬能控制項存在的意義,產品無法與技術設計相結合的理解使用;並且發現我們的智能業務部Camera自定義預覽技術雖然是使用多年,但是我們並沒有真正的形成規范,由於產品在不能夠理解系統平台(Android/iOS)給產品和研發帶來了什麼,導致產品可能會出現在不理解系統平台以及系統知識的情況下,臆想產品所謂的形態;當產品設計脫離了系統平台所支持的技術點以及設計的初衷,就會導致回歸問題的時候,出現不必要的討論,其根結就是一點:「信息不同步,知識不同步」。
所以,為了提高效率,就採用記錄和分享的方式,嘗試性推動產品、測試、研發三者對工程與架構的同步理解,更深的懂得程序架構設計意義,嘗試性通過信息同步的方式,在一個統一的知識儲備的平台下,共同完成一個更高效,和高品質的工程產品。(為了能夠讓非技術:產品設計,以及測試都能夠理解,所以,使用了更多的白話解釋)
附:強大靈活的FsCameraTextureView(第一版,自適應截取)( 第二版本版本:自適應展示)
首先,拋出幾個問題,
1)什麼是攝像頭支持的previewSize?
2)什麼是視頻或者圖片的pictureSize?
3) 如何獲取和查看攝像頭支持的PreViewSize 和PictureSize ?
4)手機預覽所見的區域SurfaceView(TextureView)與camera 的previewSize的關系是什麼?
5)為什麼會設計了兩種預覽方式view,兩種預覽方式都會有什麼樣子的效果呢?
一,概述
通過Android Camera拍攝預覽中設置setPreviewCallback實現onPreviewFrame介面,實時截取每一幀視頻流數據(簡單說來,就是通過設置一個介面,接收系統回調通知我們的每一幀數據)
二,知識點
1, camera支持的格式:
2,拍照流程
3,camera許可權
三,Android Camera中PreviewSize、 PictureSize、 SurfaceView(TextureView)之間的關系
1,PreviewSize:
相機預覽時候的能支持的尺寸,簡單的說一下,就是預覽的大小,也就是拍照前能夠看到的圖片大小。(通過Android手機相機可以試一下,這個參數設置不同,同樣的焦距下,拍攝桌子上一個固定距離的東西,看到的視野會不同)
相機的預覽尺寸,不能隨意的設置值,只能通過camera的parameters的getSupportedPreviewSizes方法,獲取支持的預覽尺寸列表,並從列表中選擇一個設置在parameters中。(通俗簡單的說就是,獲取camera中能夠支持的預覽大小合集,如果你想要查看某個預覽對應的尺寸,就把該尺寸設置到camera的屬性中即可,則camera會返回相對應尺寸的預覽數據流提供顯示)。
2,PictureSize :
指的是拍照之後,最終拍攝到的圖片大小,也就是圖片的質量。圖片尺寸同樣也只能從支持的列表中選取一個設置。 調用camera的takePicture方法(拍照)後,獲得拍照的圖像數據,注意picturesize和previewsize的寬高比也要保證一致,否則獲取的圖片會將preview時的圖像裁剪成picturesize的比例。 previewsize的解析度,只會影響預覽時的解析度,不會影響獲取圖片的解析度,所以preview只是確定了圖像的取景最大范圍。最終圖片的解析度是由picturesize來決定。 所以,最好的設置方法,例如:previewsize為1280*720,picturesize為2560*1440。(由於我們沒有拍照業務,目前這個知識,不做深究)
3,SurfaceView(TextureView)
用於展示camera預覽圖像的view,就是將preview獲得的數據,放在這個view上。所以如果preview的寬高比和SurfaceView的寬高比不一樣,就會導致看到的圖像拉伸變形。圖像拉伸變形解決的辦法:
(1)就是在確定preview的解析度後,重新設置SurfaceView寬高;
(2)如果SurfaceView寬高定死,則需要獲取一個比例適合SurfaceView尺寸的PreviewSize 的preview,盡量小的裁剪,然後填充在SurfaceView中。
4,利用圖片的顯示方式,理解Preview與SurfaceView(TextureView)顯示關系
ImageView (UI上面設計的一個控制項)與圖片bitmap 的關系,比如限定死一個ImageView的大小,但是圖片與ImageView尺寸不一致,就會有幾種方案,首先選取一張長方形1920*1080的圖片,ImageView就是紫色部分,無論長寬比都比ImageView要大。
圖片適配例1:拉伸填充ScaleType.FIT_XY :雖然被全部填充,但是整個圖片為了適配圖片已經扭曲,失真,圖片縮放到控制項大小,完全填充控制項大小展示。
圖片適配例2:等比例裁剪填充ScaleType.CENTER_CROP ,因為在該模式下,圖片會被等比縮放直到完全填充整個ImageView,並居中顯示。該模式也是最常用的模式了。如圖可以看到,圖片的高度是能完全展示出來的,但是左右部分被進行了裁剪,並沒有完全顯示。
圖片適配例3 : ScaleType.CENTER_INSIDE,此模式,用以完全展示圖片內容為目的。圖片將被等比縮放到能夠完整展示在ImageView中並居中,如果圖片大小,小於控制項尺寸,那麼就直接居中展示該圖片
圖片適配ImageView方式還有很多,就不一一列舉,這三種已經足夠重要,為什麼講解camera預覽,卻穿插了圖片的適配,其實可以這么理解,camera的preview就是由多張圖片組成,不斷的像幀動畫一樣變化,而SurfaceView就是一個載體,相當於ImageView,業務中定死了SurfaceView的大小之後,被動的承載你選擇的previewSize,來展示camera的Preview,你可以選擇類似於前面三種例子來理解preview的填充,以下會舉例說明preview的填充策略選擇有哪幾種方式,我們會採用哪種方式:
1)拉伸填充,自適應view,不可取,比如:手機的SurfaceView是整個手機的屏幕尺寸(全屏填充),或者任意尺寸比例的surfaceView,使用這種方式,就如同(圖片適配例1)的方式,導致視頻扭曲,拉伸。
2)等比例裁剪填充,目前我們項目中,採用的就是這種方式,並且提供給很多三方使用,已經成為一種獨立,並且穩定的技術實現自定義view,簡單說一下視頻的適配策略方式,SurfaceView隨便由業務方,自定義寬度大小,比如業務方選擇了1900*1000的SurfaceView, 我們的適配過程是:(1)從PreviewSize列表中選取最接近SurfaceView尺寸的PreviewSize(假設該攝像頭,只支持1920*1080,和320*640),1920*1080最接近,所以被獲取;(此處展示一下蹩腳的英文Try to find an size match aspect ratio and size,嘗試找到縱橫比與view大小比適中的一個尺寸)(2)等比例裁剪填充到SurfaceView,首先我們設計的邏輯是,先選取一個縮放比例,假設等比例1920的圖片按照SurfaceView的寬度等比例縮小到1900,而為了不讓Preview失真,則高度1080等比例縮小的值是1068.75(等比例方程式,這里就不重復初中的知識,請自行計算),所以圖片被壓縮成為1900*1068這個尺寸,依舊保證圖片完整,並且不失真。(3)將等比例縮減的圖片,1900*1068進行顯示在1900*1000的SurfaceView中,就會有一種效果類似(圖片適配例2),寬度全部展示,高度被裁剪。(如同 圖片適配例2中左右部分裁剪一樣的道理)
3)完全展示camera內容的縮放填充(類似圖片適配例3),我們打開任意一部手機的camera,預覽圖像都沒有全屏幕展示,類似拍照功能,所見即所得,PreviewSize是多少,就顯示什麼樣子的比例尺寸,以及最後生產的照片比例就是多少,我們的自定義view,也可以隨意設置大小,此模式下,用以完全展示camera內容為目的。Preview將被等比縮放到能夠完整展示在SurfaceView中並居中,但是可能會有部分位置無法填充(類似圖片適配例3顯示效果)。
(該方式只是進行了技術儲備,由於沒有業務場景設計,所以沒有使用,目前只是儲備了這樣的自定義控制項)
四,靈活的自定義TextureView預覽控制項
FsCameraTextureView(第一版,自適應截取):等比例裁剪填充,方式(適配方式2),採用前面說的適配方式2,而產出的一種自定義view,2019年5月產出至今,在金融APP,以及商城的app中使用,經過逐步優化,和多版本檢驗,目前該控制項,擁有以下特點: 1)穩定:目前各個使用場景,均無邏輯崩潰,內存泄漏,線程等任意問題; 2)靈活:隨意設置預覽view的尺寸大小,自適應任意業務設計;不僅僅滿足刷臉業務,並且滿足任意相機預覽業務方使用; 3)提高效率,減輕工作量:使用簡單,操作步驟簡潔,接入只需要兩步;減輕接入端,或者想要使用相機預覽的業務的工作量,不需要重復造車,並且安全穩定。
輸出的業務方有(經不完全統計):(目前業務為保密進行公網保密處理)1)**創新科技業務部-區塊鏈部門 2)泰國人臉識別業務SDK3)S D**Bank 人臉業務4)核驗身份證業務5)HT**Bank 人臉業務 6)**雲,商業平台部門
FsAllPreviewCameraTextureView(技術儲備版,全預覽模式顯示):完全展示camera內容的縮放填充,採用前面說的(適配方式3)適合拍照相關的業務使用,優點同樣是,外部業務隨意改變view大小,可以自適應view,由於目前沒有業務方使用,暫時做儲備,不深入講解。
如果可以控制項開源成功,後期,我將開源這兩個控制項,讓更多的使用方使用,我們也希望共同技術進步,提高工程產出的使用能力。
預計下一次分享內容是(臨時命名)
1)人臉核驗內存和線程爆表到泄漏為零
2)分享七年前參於的Scrum(如何提高崗位間效率所定製的敏捷開發過程)
本文參考:
https://www.jianshu.com/p/32e335d5b842
https://www.cnblogs.com/skyseraph/archive/2012/03/26/2418665.html
2. 如何把android手機畫面實時傳遞到電腦上
首先,要實現該功能必須在WINDOWS系統上作如下的設置:
1、點擊【控制面板】裡面的【管理工具】
5、在手機點擊播放後,在電腦的Windows Media Player上會自動顯示手機上的圖片
3. Android Camera 做實時視頻採集傳輸的時候怎麼才能讓幀率達到100FPS
要想幀率高,有三條路可走:
1.降低採集解析度。但這樣會降低視頻效果。
2.提高硬體速度,使用高性能的處理器,這是最快的方法。
3.基於現狀,改進軟體演算法,提高代碼執行效率。
可以想出來的只有這幾條措施了。但基本想要達到100FPS,有點困難。
4. android視頻流處理
《android逆向視頻》網路網盤資源免費下載
鏈接:https://pan..com/s/1W1NAE-AeKbz0bb6E4mdXfA
5. 如何在Android實現一個流媒體伺服器
現在,越來越多的朋友用上了寬頻,如果僅僅只是將寬頻用來下載軟體、觀看電影,那未免太浪費了。假如你的機器性能還不錯的話,是否設想過將它架設為一台流媒體伺服器。這樣就可以與親朋好友共享美妙的音樂或最新的電影,那種網路DJ的感受可真是無與倫比呀。 就現在的主流計算機硬體而言,搭建一台網路流媒體伺服器應該沒有什麼困難,只要滿足Pentium III 450MHz、256MB內存容量、足夠的硬碟空間即可。但如果你還沒有用上寬頻,那麼還是放棄吧,否則那時斷時續的傳播質量會讓朋友們罵死你。
架設網路流媒體伺服器
所謂流媒體技術,是指將連續的影像和聲音信息經過壓縮處理後放在網站伺服器上,讓用戶能夠一邊下載一邊觀看、收聽(即所謂的「在線欣賞」),而不需要等整個壓縮文件下載到自己的機器上才可以欣賞的網路傳輸技術。目前,在這個領域中的競爭者主要有微軟、RealNetworks、Apple三家公司,例如微軟新近發布了Windows Media Services 9、RealNetworks公司新近發布的Helix Platform、Apple新近發布的Darwin streaming server 4.1,意圖在流媒體領域大幹一場。
一般來說,一個完整的流媒體服務系統需要三個部分組成:編碼器、流伺服器和播放器。編碼器通過對內容來源(如MP3文件或者麥克風輸入)進行編碼,並將編碼過的內容發送到流伺服器;流伺服器再將它們發布到Internet,這樣客戶端的播放器只要連接到流伺服器就可以進行在線播放了。
利用Winamp架設MP3網路電台
當我們靜靜地在欣賞美妙的MP3音樂時,你是否曾經考慮過將這些原本屬於個人的MP3音樂通過網路在區域網內進行發布,甚至還可以通過Internet進行發布?這樣就可以讓遍布世界的朋友們與你一起共享MP3音樂之旅。其實,要做到這一點並不難,你只要將本機創建為一台MP3流媒體伺服器,將自己所喜愛的MP3音樂不停播放,然後通知朋友們訪問你的這台MP3伺服器就可以了。
說起MP3的播放,使用最廣泛的莫過於Winamp了。對於MP3流媒體服務這個領域,Winamp的開發者Nullsoft公司當然不會放棄,專門發布了面向MP3的流伺服器SHOUTcast Server。雖然它的功能沒有Windows Media Server和Real Server強大,但它不僅對硬體的要求極低,更關鍵的是完全免費,使用起來沒有後顧之憂。另外你還需要下載一個名為SHOUTcast DSP Plug-in的插件,只有安裝了這個不起眼的插件,Winamp才能支持流媒體服務。
首先打開Winamp(請注意版本號必須在2.22以上),切換到「Options」 | 「Preferences」| 「DSP/Effect」標簽頁,選中「Nullsoft SHOUTcast Source DSP v1.8.2a[dsp_sc.dll]」下的「Configure」按鈕。打開「SHOUTcast Source」窗口,選擇「Output」標簽頁,如圖1所示,在「Address」欄內填入本機的IP地址。如果你想在Internet上廣播MP3音樂,則必須鍵入本機的外部IP地址,然後就可以從程序組中運行SHOUTcast DAAS(GUI)程序以啟動SHOUTcast服務。這時系統會自動連接到http://yp.shoutcast.com伺服器,接下來請返回圖1窗口點擊「Connect」按鈕。如果連接成功,該按鈕會變為「disconnect」字樣,這樣我們就完成了在本機架設MP3流伺服器的全部過程。
架設REAL格式的視頻點播中心
如果是架設視頻點播伺服器,那麼選擇Real格式是非常明智的。因為RealProcer Plus這款功能強大的軟體操作相當簡單,每次使用時會彈出一個向導對話框進行操作提示。目前最新版本是10.0,我們只要選擇8.5.1以上的版本即可。
從「工具」菜單下選擇「創建網頁」命令,此時會彈出一個如圖2所示的向導式對話框,點擊「前進」按鈕選擇你希望用於創建Web頁面的Real多媒體文件。隨後RealProcer會詢問是創建「彈出式播放器」還是「嵌入式播放器」,一般建議選擇後者,因為這樣所需要的系統資源更低,當然啟動速度也更快。至於播放器的界面,可以選擇「標准播放器」,很快就可以創建成功。
最後,RM文件對象所在的目錄會增加一些文件,請將這些文件與RM對象一起上傳,不過要注意保證RM文件與HTML文件在同一目錄下,否則播放器可能無法找到播放對象。
架設WMP流媒體伺服器
微軟的手伸得很長,什麼領域都要插足一下。憑借著Windows操作系統的影響力,Windows Media Player市場佔有率越來越高,而微軟的*.asf、*.wmv、*.wma、*.avi等格式也開始被越來越多的用戶所接受。
架設WMP流媒體伺服器,你需要安裝Windows Media Encoder才行,目前最新版本是9.0簡體中文版。如圖3所示,我們應該在這里選擇「廣播實況事件」,接著選擇用來編碼的音頻和視頻設備。注意請事先將音頻和視頻設備與計算機正確連接,否則會無法檢測到。接著你還需要指定服務和發布點,當然也可以使用現有的發布點。然後Windows Media Encoder會自動創建伺服器,並給出HTTP連接地址與區域網內部地址,請記住這些內容,最後點擊「開始」按鈕正式啟動WMP流媒體伺服器。
接下來,我們就可以將剛才記下的HTTP連接地址與區域網內部地址告訴給朋友們。他們只要打開IE,輸入正確的IP地址和埠號,很快就可以訪問WMP流媒體伺服器。
架設QT流媒體伺服器
平時,我們見到的大多是打造MWF(矢量地圖窗口文件,Map Window File)或RM流伺服器,可是你可知道QuickTime(以下簡稱QT)流媒體伺服器應該如何來打造嗎?其實,藉助蘋果的QuickTime Streaming Server工具,我們可以在短時間內快速打造出一台QT流伺服器。
首先我們要准備一些工具,QuickTime媒體播放工具當然是必不可少的。目前最新版本是6.5簡體中文版,到處都可以找到,或者直接到蘋果公司的網站下載,並且需要在伺服器和客戶端同時安裝。Perl語言解析器,最低版本要求是5.0以上。QuickTime Streaming Server與用戶見面最早是在1999年,當時以其開放源代碼和基於標準的實時傳輸協議/實時流協議(RTP/RTSP)引擎深深地動搖了流媒體工業的基礎,目前的最新版本是5.0,下載文件共9.2MB。
從http://developer.apple.com/darwin/projects/streaming/地址可以免費下載,但你必須擁有Apple的注冊用戶名才能登錄(注冊是免費的),這里有Mac OS X、Red Hat、Solaris、Windows NT/2000/XP等版本可供選擇。下載回來的是一個自解壓文件,釋放後執行Install.bat運行安裝程序,運行過程在命令提示符窗口中完成,最後還需要設置登錄用戶名、密碼,如圖4所示,當看到「Setup Complete!」的提示信息時即大功告成。QT流媒體伺服器建設過程和RM類似,在這里就不再贅述。
如何共享音頻和視頻
共享音頻
前面,我們利用Winamp、SHOUTcast Server將本機架設為一台MP3流伺服器,那麼該如何讓遍布天南海北的朋友或區域網中的同事欣賞這些美妙音樂呢?
這有兩種方法:一種是打開Winamp,從「Play」菜單下選擇「Location」命令,或者直接鍵入「Ctrl-L」組合鍵打開一個對話框,然後在這里鍵入MP3流伺服器的URL地址或者IP地址、埠號(預設為8000),例如「http://192.168.0.1:8000」或者「http://61.277.1.24:8000」即可收聽;另一種方法則更為簡單,從IE中打開「http://192.168.0.1:8000」進入Web管理頁面,如圖5所示,然後點擊「收聽」按鈕就可以在線收聽MP3流音樂。
共享視頻
雖然蘋果的QuickTime Player的市場佔有率遠遠不如Real或Windows Media Player,但忠實的用戶依然不少。而且蘋果畢竟是網路流媒體的開山鼻祖,因此許多最新大片都是採用QT格式。
首先必須在機器上啟動QT服務,然後通知朋友們在遠程計算機中打開QuickTime。從「文件」菜單中選擇「在新的播放窗口中打開URL」命令,鍵入「rtsp://server/file.mov」來訪問QT流伺服器以實現遠程播放。這里的「server」是伺服器的IP地址,「file.mov」是媒體文件名,默認的RTSP傳輸埠是554埠。如果網路連接沒有什麼問題的話,如圖6所示,那麼你很快就可以連接成功。
建立播放列表或點播系統
辛辛苦苦架設了一台流媒體伺服器,我們還可以建立播放列表或點播系統,甚至可以進行網路直播,反正已經用上了寬頻,不用也是浪費。
配置QT流媒體伺服器
打開IE,在地址欄中輸入「http://server:1220」,這里的「server」代表伺服器的IP地址。如果前面的配置沒有什麼問題的話,很快就會進入如圖7所示的管理頁面,這里以列表形式顯示了當前的系統資源佔用情況和相關的伺服器信息。我們可以在這里查看連接到伺服器的用戶類型、IP地址、數據速率、數據傳輸量、包丟失比例、連接時間、連接文件等內容,也可以在這里設置映射文件夾、加密傳輸、最大連接用戶數、分配帶寬、重置密碼、更改埠,如果你需要的話,還可以查看錯誤日誌和操作日誌。
創建播放列表
點擊圖7窗口右側的「New MP3 Playlist」或「New Movie Playlist」按鈕,我們可以創建一個MP3或影片的播放列表。不過這里需要說明的是,你需要將相關的媒體文件復制到C:Program FilesDarwin Streaming ServerMovies文件夾中才行。
如圖8所示,我們可以在這里通過「Weight」旁邊的小三角箭頭重新調整播放列表的播放順序,可惜的是QuickTime Streaming Server對簡體中文的支持十分差勁,顯示的竟然是一些亂碼字元。最後,點擊窗口右下角的「Save Changes」按鈕就可以將這份新建的播放列表保存下來,以後如果需要更改的話可以選擇「Edit Playlist」重新配置。
不過,如果你希望其他用戶也能訪問這份播放列表文件,還必須點擊「Avaliable Playlists」列表框中的「Status」下的播放按鈕,也就是讓「Status」列的「Stopped」變為「Playing」才行。
實現網路直播
如果你還想在播放完MP3歌曲後說上一段話,那麼簡單的很,只要一個話筒就行了。不過,還需要在Winamp中進行一些設置,如圖9所示,在「Input Device」下拉列表框中選擇「Soundcard Input」項,這樣才會出現圖中的SoundCard Mixer設置項。如果使用默認的設置「Winamp(Recommended)」的話就只有Input Levels一項了,下面還有「Music Level」、「BGMusic Level」、「Mic Level」幾個滑塊可以調節音量的大小,而「Fade Time」是用來設
置移出時間值。
現在,你無需進行其它設置,准備一番後,清清嗓子,點擊「Push to Talk」按鈕,然後再按下「Lock」按鈕鎖定當前話音輸入模式。接下來就可以對著麥克風開始你的網路直播之旅了,結束請再次按下「Lock」按鈕解鎖。
6. 基於的Android視頻監控系統實現的疑問
做過一個類似的,不過得用瀏覽器, 當時是用的 html5的 websocket進行數據傳輸。這是內段 js代碼
functioninitialize(){
console.log("Initializing;room=${roomKey}.");
card=document.getElementById("card");
localVideo=document.getElementById("localVideo");
miniVideo=document.getElementById("miniVideo");
remoteVideo=document.getElementById("remoteVideo");
resetStatus();
openChannel();
getUserMedia();
}
functiongetUserMedia(){
try{
navigator.webkitGetUserMedia({
'audio':true,
'video':true
},onUserMediaSuccess,onUserMediaError);
console.log(".");
}catch(e){
try{
navigator.webkitGetUserMedia("video,audio",
onUserMediaSuccess,onUserMediaError);
console
.log(".");
}catch(e){
alert("webkitGetUserMedia()failed.:flags?");
console.log(":"
+e.message);
}
}
}
functiononUserMediaSuccess(stream){
console.log(".");
varurl=webkitURL.createObjectURL(stream);
localVideo.style.opacity=1;
localVideo.src=url;
localStream=stream;
//CallercreatesPeerConnection.
if(initiator)
maybeStart();
}
functionmaybeStart(){
if(!started&&localStream&&channelReady){
setStatus("Connecting...");
console.log("CreatingPeerConnection.");
createPeerConnection();
console.log("Addinglocalstream.");
pc.addStream(localStream);
started=true;
//Callerinitiatesoffertopeer.
if(initiator)
doCall();
}
}
functiondoCall(){
console.log("Sendingoffertopeer.");
if(isRTCPeerConnection){
pc.createOffer(setLocalAndSendMessage,null,mediaConstraints);
}else{
varoffer=pc.createOffer(mediaConstraints);
pc.setLocalDescription(pc.SDP_OFFER,offer);
sendMessage({
type:'offer',
sdp:offer.toSdp()
});
pc.startIce();
}
}
(sessionDescription){
pc.setLocalDescription(sessionDescription);
sendMessage(sessionDescription);
}
functionsendMessage(message){
varmsgString=JSON.stringify(message);
console.log('發出信息:'+msgString);
path='message?r=${roomKey}'+'&u=${user}';
varxhr=newXMLHttpRequest();
xhr.open('POST',path,true);
xhr.send(msgString);
}
頁面載入完之後會調用initialize方法,initialize方法中調用了getUserMedia方法,這個方法是通過本地攝像頭獲取視頻的方法,在成功獲取視頻之後發送連接請求,並在客戶端建立連接管道,最後通過sendMessage向另外一個客戶端發送連接的請求