国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android USBCamera投屏 - 利用UVC協(xié)議將手機(jī)上的畫面有線投屏到Android車機(jī)的屏幕上

這篇具有很好參考價值的文章主要介紹了Android USBCamera投屏 - 利用UVC協(xié)議將手機(jī)上的畫面有線投屏到Android車機(jī)的屏幕上。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1. 背景

一個需求 : 要將手機(jī)上的畫面和音頻 投屏 到 車機(jī)的Android屏幕上。

車機(jī)有一個支持OTG的USB-A口,由于設(shè)備有限,我們有一個USB-A轉(zhuǎn)HDMI轉(zhuǎn)接口,一跟HDMI線,一個USB-C的拓展塢 (包括HDMI口,兩個USB-A口,一個網(wǎng)口),我們將這幾根線接在一起,成功將手機(jī)和車機(jī)連在了一起。

接著,我們在網(wǎng)上找到了一個 jiangdongguo/AndroidUSBCamera ,我們使用Android Studio打開編譯安裝到車機(jī),并將車機(jī)的Usb modeDevice mode切換為Host Mode,這個時候,AndroidUSBCamera會彈出打開USB攝像頭的彈框,我們點擊同意,就可以看到手機(jī)上的畫面顯示到車機(jī)上了。

使用yorkZJC/UvcCameraDemo這個庫也可以成功

和這個相關(guān)的所有的項目,基本都是基于 saki4510t/UVCCamera 這個開源項目來改的

那么,我們有了以下兩個疑問

  • 是如何讀取到手機(jī)上的畫面,顯示到車機(jī)上的 ?
  • 為什么只有畫面,沒有聲音 ?

2. 是如何讀取到手機(jī)上的畫面,顯示到車機(jī)上的 ?

帶著這個疑問,看了下AndroidUSBCamera的代碼。

原來,現(xiàn)在所有主流操作系統(tǒng)都已提供UVC設(shè)備驅(qū)動,因此符合UVC規(guī)格的硬件設(shè)備在不需要安裝任何的驅(qū)動程序下即可在主機(jī)中正常使用。使用UVC技術(shù)的包括攝像頭、數(shù)碼相機(jī)、類比影像轉(zhuǎn)換器、電視棒及靜態(tài)影像相機(jī)等設(shè)備。

UVC全稱USB Video Class,即 USB視頻類,是一種為USB視頻捕獲設(shè)備定義的協(xié)議標(biāo)準(zhǔn)。

是Microsoft與另外幾家設(shè)備廠商聯(lián)合推出的為USB視頻捕獲設(shè)備定義的協(xié)議標(biāo)準(zhǔn),已成為USB org標(biāo)準(zhǔn)之一。

而項目中,對USB Camera (UVC設(shè)備)的使用和視頻數(shù)據(jù)采集進(jìn)行了高度封裝。

//開始進(jìn)行預(yù)覽
private void startPreview() {
    mCameraHelper.startPreview(mUVCCameraView);
}

通過startPreview方法,會調(diào)用到handleStartPreview方法

public void handleStartPreview(final Object surface) {
    if (DEBUG) Log.v(TAG_THREAD, "handleStartPreview:");
    if ((mUVCCamera == null) || mIsPreviewing) return;
    try {
        mUVCCamera.setPreviewSize(mWidth, mHeight, 1, 31, mPreviewMode, mBandwidthFactor);
        // 獲取USB Camera預(yù)覽數(shù)據(jù),使用NV21顏色會失真
        // 無論使用YUV還是MPEG,setFrameCallback的設(shè)置效果一致
        mUVCCamera.setFrameCallback(mIFrameCallback, UVCCamera.PIXEL_FORMAT_YUV420SP);
    } catch (final IllegalArgumentException e) {
        try {
            // fallback to YUV mode
            mUVCCamera.setPreviewSize(mWidth, mHeight, 1, 31, UVCCamera.DEFAULT_PREVIEW_MODE, mBandwidthFactor);
        } catch (final IllegalArgumentException e1) {
            callOnError(e1);
            return;
        }
    }
    if (surface instanceof SurfaceHolder) {
        mUVCCamera.setPreviewDisplay((SurfaceHolder) surface);
    }
    if (surface instanceof Surface) {
        mUVCCamera.setPreviewDisplay((Surface) surface);
    } else {
        mUVCCamera.setPreviewTexture((SurfaceTexture) surface);
    }
    mUVCCamera.startPreview();
    mUVCCamera.updateCameraParams();
    synchronized (mSync) {
        mIsPreviewing = true;
    }
    callOnStartPreview();
}

最終調(diào)用到nativeSetPreviewDisplay方法

static jint nativeSetPreviewDisplay(JNIEnv *env, jobject thiz,
	ID_TYPE id_camera, jobject jSurface) {

	jint result = JNI_ERR;
	ENTER();
	UVCCamera *camera = reinterpret_cast<UVCCamera *>(id_camera);
	if (LIKELY(camera)) {
		ANativeWindow *preview_window = jSurface ? ANativeWindow_fromSurface(env, jSurface) : NULL;
		result = camera->setPreviewDisplay(preview_window);
	}
	RETURN(result, jint);
}

這時候,我們就可以預(yù)覽到手機(jī)上的畫面了。

3. 為什么只有畫面,沒有聲音 ?

這個時候,我們可以發(fā)現(xiàn),車機(jī)上只顯示出了畫面,沒有聲音播放的。

看了下AndroidUSBCamera里的代碼,當(dāng)點擊了錄像按鈕,調(diào)用startPusher方法,回調(diào)里type==0,表示是aac audio stream的,但實際測試中,永遠(yuǎn)都只會收到type==1的情況,而收不到type==0的情況。

mCameraHelper.startPusher(params, new AbstractUVCCameraHandler.OnEncodeResultListener() {
    @Override
    public void onEncodeResult(byte[] data, int offset, int length, long timestamp, int type) {
        
        // type = 1,h264 video stream
        if (type == 1) {
            FileUtils.putFileStream(data, offset, length);
        }
        // type = 0,aac audio stream
        if(type == 0) {
            trackplayer.write(data, offset, length);//往track中寫數(shù)據(jù)
        }
    }

    @Override
    public void onRecordResult(String videoPath) {
        if(TextUtils.isEmpty(videoPath)) {
            return;
        }
        new Handler(getMainLooper()).post(() -> Toast.makeText(USBCameraActivity.this, "save videoPath:"+videoPath, Toast.LENGTH_SHORT).show());
    }
});

在Github 的issue上,我也看到了這個問題 : 可以支持USB的音頻輸入嗎?

看上去大家也有同樣的問題
Android USBCamera投屏 - 利用UVC協(xié)議將手機(jī)上的畫面有線投屏到Android車機(jī)的屏幕上

這時候,找到的USB攝像頭這個應(yīng)用市場上的app,卻是可以在投屏的同時,播放出聲音的。

反編譯了這個apk,可以看到它的so里面,有一個libUSBAudio.so,看上去就是用來處理音頻的so
Android USBCamera投屏 - 利用UVC協(xié)議將手機(jī)上的畫面有線投屏到Android車機(jī)的屏幕上

我們在網(wǎng)上查找了一下這個so,得知

libusb是一底層的API,可以跨平臺實現(xiàn)。

基于libusb可以獲取到usb mac的pcm流數(shù)據(jù),從而可以讀取到音頻。

libusb庫使用C語言編寫,在Android中使用該庫需要用到JNI技術(shù)。

github : libusb/libusb:用于訪問 USB 設(shè)備的跨平臺庫

然后,我們找到了一個libusb的庫 jim0608/android_usbaudio: 基于libusb,實現(xiàn)無驅(qū)動獲取USBAudio

當(dāng)然,這個庫本身是有點問題的,但大體思路可以參考

由于libusb庫使用到了JNI,所以我們需要先配置好NDK,其對應(yīng)版本為21.0.6113669

Android USBCamera投屏 - 利用UVC協(xié)議將手機(jī)上的畫面有線投屏到Android車機(jī)的屏幕上
Android USBCamera投屏 - 利用UVC協(xié)議將手機(jī)上的畫面有線投屏到Android車機(jī)的屏幕上

代碼中有一個OnDeviceConnectListener,當(dāng)把視頻線插到車機(jī)的USB-A口的時候,

onAttach方法就會被調(diào)用,這個時候會調(diào)用requestPermission去請求權(quán)限。

當(dāng)連接上的時候,會記錄下mCtrlBlockmCtrlBlock

private final USBMonitor.OnDeviceConnectListener mOnDeviceConnectListener = new USBMonitor.OnDeviceConnectListener() {

        @Override
        public void onAttach(UsbDevice device) {
            Log.i(TAG, "onAttach: " + device);
            mUSBMonitor.requestPermission(device);
        }

        @Override
        public void onDettach(UsbDevice device) {
            Log.i(TAG, "onDettach: " + device);
        }
    
    	@Override
        public void onConnect(UsbDevice device, USBMonitor.UsbControlBlock ctrlBlock, boolean createNew) {
            Log.i(TAG, "onConnect: " + device);
            for (int interfaceIndex = 0; interfaceIndex < device.getInterfaceCount(); interfaceIndex++) {
                if (device.getInterface(interfaceIndex).getInterfaceClass() == USB_CLASS_AUDIO){
                    mCtrlBlock = ctrlBlock;
                    break;
                }
            }

            mAudioDevice = device;
        }

    	//...省略...
    };

接著,我們就可以去初始化音頻了

 mCtrlBlock = mUSBMonitor.getDevice(mDevice);
 mUsbAudio.initAudio(mCtrlBlock);

然后再開始捕獲

mUsbAudio.startCapture();

這個時候,我們在手機(jī)端播放音樂,車機(jī)的音響就會輸出聲音了。

播放聲音其實是用過AudioTrack來播放的

在Android中,播放聲音可以用MediaPlayer和AudioTrack

區(qū)別如下

MediaPlayer AudioTrack
支持格式 MP3,AAC,WAV,OGG,MIDI等 已經(jīng)解碼的PCM流,或WAV格式的音頻文件(大部分是PCM流)
解碼器 在framework層創(chuàng)建對應(yīng)音頻解碼器 不創(chuàng)建解碼器,所以只能播放無需解碼的WAV文件
聯(lián)系 在framework層還是會創(chuàng)建AudioTrack

這里,有個采樣率的問題,得找到合適的采樣率,否則會有播放聲音不清晰、白噪音等情況。

結(jié)合在一起使用

AndroidUSBCameraandroid_usbaudio結(jié)合起來,就可以實現(xiàn)既播放視頻,同時播放出聲音的效果了。

4. AudioTrack基礎(chǔ)的使用

最后,介紹下AudioTrack基礎(chǔ)的使用

AudioTrack 的構(gòu)造方法
public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode) { ... }
streamType 音頻流類型
AudioManager.STREAM_MUSIC:用于音樂播放的音頻流。
AudioManager.STREAM_SYSTEM:用于系統(tǒng)聲音的音頻流。
AudioManager.STREAM_RING:用于電話鈴聲的音頻流。
AudioManager.STREAM_VOICE_CALL:用于電話通話的音頻流。
AudioManager.STREAM_ALARM:用于警報的音頻流。
AudioManager.STREAM_NOTIFICATION:用于通知的音頻流。
AudioManager.STREAM_BLUETOOTH_SCO:用于連接到藍(lán)牙電話時的手機(jī)音頻流。
AudioManager.STREAM_SYSTEM_ENFORCED:在某些國家實施的系統(tǒng)聲音的音頻流。
AudioManager.STREAM_DTMFDTMF音調(diào)的音頻流。
AudioManager.STREAM_TTS:文本到語音轉(zhuǎn)換(TTS)的音頻流。
sampleRateInHz 采樣率

播放的音頻每秒鐘會有多少次采樣,一般為44100,最好是通過代碼動態(tài)獲取采樣率,其他常見的采樣率還有

96000, 
88200, 
64000, 
48000, 
44100, 
32000, 
24000, 
22050, 
16000, 
12000, 
11025, 
8000, 
7350, 

如果發(fā)現(xiàn)播放后聲音不清晰、白噪音等情況,可以調(diào)整這個采樣率值

channelConfig 聲道數(shù)

單聲道AudioFormat.CHANNEL_IN_MONO,雙聲道AudioFormat.CHANNEL_IN_STEREO,建議選擇單聲道

audioFormat 數(shù)據(jù)位寬

只支持AudioFormat.ENCODING_PCM_8BIT(8bit)AudioFormat.ENCODING_PCM_16BIT(16bit)兩種,后者支持所有Android手機(jī)

bufferSizeInBytes 音頻緩沖區(qū)大小

建議使用AudioTrack.getMinBufferSize()這個方法獲取

int bufSize = AudioTrack.getMinBufferSize(SAMPLE_RATE_HZ,channelConfig, AudioFormat.ENCODING_PCM_16BIT);
mode 播放模式

有兩種播放模式:

  • MODE_STATIC : 一次性將所有數(shù)據(jù)都寫入播放緩沖區(qū)中,簡單高效,一般用于鈴聲,系統(tǒng)提醒音,內(nèi)存比較小的。
  • MODE_STREAM : 需要按照一定的時間間隔,不斷的寫入音頻數(shù)據(jù),理論上它可以應(yīng)用于任何音頻播放的場景。
AudioTrack 播放示例

初始化

int bufSize = AudioTrack.getMinBufferSize(SAMPLE_RATE_HZ,AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);

track = new AudioTrack(AudioManager.STREAM_MUSIC,
                       SAMPLE_RATE_HZ,
                       channelConfig,
                       AudioFormat.ENCODING_PCM_16BIT,
                       bufSize,
                       AudioTrack.MODE_STREAM);
track.play();

寫入數(shù)據(jù)

public void pcmData(byte[] data) {
    track.write(data, 0, data.length);
}

停止播放,銷毀資源

if(audioTrack.getState() != AudioTrack.STATE_UNINITIALIZED){
    audioTrack.stop();
    audioTrack.release();
}

5.本文代碼下載

本文Demo下載地址 : Android UVC USBCamera投屏Demo

參考 :
一篇文章帶你了解Android Usb攝像頭
這可能是介紹Android UvcCamera最詳細(xì)的文章了
Android音頻系統(tǒng)AudioTrack使用方法詳解
ffmpeg開發(fā)之旅(8):Android UVC Camera(USB攝像頭)開發(fā)核心技術(shù)詳解
Android音視頻錄制與播放功能簡述
Android UCV 同時打開多路攝像頭
Android從USB聲卡錄制高質(zhì)量音頻-----使用libusb讀取USB聲卡數(shù)據(jù)
基于libusb庫、uac協(xié)議,獲取Audio聲音數(shù)據(jù)
Android/linux從usb聲卡獲取音頻(使用libusb庫)—監(jiān)聽“純麥”(五)文章來源地址http://www.zghlxwxcb.cn/news/detail-482329.html

到了這里,關(guān)于Android USBCamera投屏 - 利用UVC協(xié)議將手機(jī)上的畫面有線投屏到Android車機(jī)的屏幕上的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Android Studio 支持安卓手機(jī)投屏

    Android Studio 支持安卓手機(jī)投屏

    有時當(dāng)我們在線上做技術(shù)分享或者功能演示時,希望共享連接中的手機(jī)屏幕,此時我們會求助 ApowerMirror,LetsView,Vysor,Scrcpy 等工具。如果你是一個 Android Developer,那么現(xiàn)在你有了更好的選擇。 自 Android Studio Electric Eel (電鰻)起支持了手機(jī)投屏,且功能非常強(qiáng)大: 手機(jī)屏幕

    2024年01月17日
    瀏覽(33)
  • Android中相機(jī)(Camera)畫面旋轉(zhuǎn)角度分析:手機(jī)攝像頭的“正向”、手機(jī)畫面自然方向、相機(jī)畫面的偏轉(zhuǎn)角度

    #.概述: ?? ?1.如同人眼看東西分上下一樣,攝像頭也有其“正向”,正常情況下,Android手機(jī)后置、前置攝像頭的“正向”朝向為手機(jī)的“右側(cè)”(默認(rèn)如此,除非手機(jī)廠商修改設(shè)置)。 (這里運(yùn)行代碼做過測試發(fā)現(xiàn),前置攝像頭也是以右側(cè)為正向,而不是有些資料上說的

    2024年02月14日
    瀏覽(26)
  • scrcpy之將Android手機(jī)投屏到Linux電腦實踐

    scrcpy之將Android手機(jī)投屏到Linux電腦實踐

    參考:https://zhuanlan.zhihu.com/p/366378837 電腦端安裝投屏程序 手機(jī)端設(shè)置 手機(jī)端無需安裝任何軟件,只需開啟【開發(fā)者選項】-【USB調(diào)試】及相關(guān)選項,比如我開啟了【USB調(diào)試、USB調(diào)試(安全設(shè)置)、無線調(diào)試、USB安裝】 開啟【USB調(diào)試】相關(guān)選項后,用USB數(shù)據(jù)線連接電腦與手機(jī),

    2024年02月09日
    瀏覽(23)
  • 如何通過 nginx 實現(xiàn)遠(yuǎn)程投屏并控制 android 手機(jī)

    操作步驟 本地電腦 Local-A.? ?遠(yuǎn)程電腦 Remote-B 和 跟 Remote-B 通過 USB 連接的手機(jī) C 1. 手機(jī) C 連接到?Remote-B 2. Remote-B? 通adb tcpip port 將臺架的adb設(shè)置為以太網(wǎng)模式,從而使臺架的adb服務(wù)可以被端口綁定。 # enable adb ethernet connection adb tcpip 5555 配置 nginx 5. 修改跳板機(jī)nginx配置,將端

    2024年02月12日
    瀏覽(25)
  • C++版Android實時投屏軟件系統(tǒng)源碼,安卓手機(jī)投屏軟件源碼,無需root權(quán)限

    C++版Android實時投屏軟件系統(tǒng)源碼,安卓手機(jī)投屏軟件源碼,無需root權(quán)限

    QtScrcpy 可以通過 USB / 網(wǎng)絡(luò)連接Android設(shè)備,并進(jìn)行顯示和控制。無需root權(quán)限。 同時支持 GNU/Linux ,Windows 和 MacOS 三大主流桌面平臺。 完整代碼下載地址:C++版Android實時投屏軟件系統(tǒng)源碼 它專注于: 精致 (僅顯示設(shè)備屏幕) 性能 (30~60fps) 質(zhì)量 (1920×1080以上) 低延遲 (35~70ms) 快速啟

    2024年02月05日
    瀏覽(23)
  • 使用互傳APP實現(xiàn)Android手機(jī)投屏到windows電腦

    目前自己實現(xiàn)的條件: 1.自用VIVO品牌的手機(jī)(每個,手機(jī)品牌的自帶互傳或者投屏APP不一樣,VIVO叫做“互傳APP”。) 2.PC(自用win11,應(yīng)該XP、win7/10都可以。)安裝“互傳PC端” 3.PC和手機(jī)在同一個路由器下。 具體步驟: 1,打開PC端互傳軟件 2.手機(jī)互傳APP內(nèi)掃碼下圖PC端的二

    2024年02月14日
    瀏覽(20)
  • Android Studio新功能-設(shè)備鏡像Device mirroring-在電腦側(cè)顯示手機(jī)實時畫面并可控制

    Android Studio新功能-設(shè)備鏡像Device mirroring-在電腦側(cè)顯示手機(jī)實時畫面并可控制

    下載最新的灰測版本-蜥蜴 成功運(yùn)行到真機(jī)后,點擊右側(cè)Running Devices選項卡,再點擊+號 選中當(dāng)前設(shè)備; 非常絲滑同步,在電腦側(cè)也可以順暢控制真機(jī) 該功能大大方便了我們視線保持在顯示器上專注開發(fā),并且便于與UI視覺進(jìn)行校準(zhǔn)與比對。 Device mirroring You can now mirror your p

    2024年02月08日
    瀏覽(21)
  • 探索Android USBCamera:一款開源的USB攝像頭應(yīng)用

    項目地址:https://gitcode.com/jiangdongguo/AndroidUSBCamera 本文將帶您走進(jìn)Android USBCamera項目,這是一個強(qiáng)大的開源庫,允許Android設(shè)備通過USB連接物理相機(jī)并作為系統(tǒng)默認(rèn)攝像頭使用。無論您是開發(fā)者、攝影師還是對移動設(shè)備攝影有獨特需求的用戶,這個項目都值得您的關(guān)注。 Android

    2024年04月27日
    瀏覽(34)
  • UVC1.5協(xié)議 2

    UVC1.5協(xié)議 2

    提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 目錄 文章目錄 前言 一、UVC拓?fù)浣Y(jié)構(gòu) 二、UVC描述符以及單元 ? UVC協(xié)議是USB下的一個子類 ,UVC就是USB video class ,是 USB視頻捕獲設(shè)備定義的協(xié)議標(biāo)準(zhǔn)。USB設(shè)備可能具備很多功能比如一個攝像頭可能集合了

    2023年04月08日
    瀏覽(15)
  • 使用JavaCV和Spring Boot搭建HTTP-FLV直播服務(wù):實時播放RTSP、RTMP和桌面投屏畫面

    使用JavaCV和Spring Boot搭建HTTP-FLV直播服務(wù):實時播放RTSP、RTMP和桌面投屏畫面 摘要: 在本文中,我們將探討如何使用JavaCV和Spring Boot構(gòu)建一個簡單的HTTP-FLV直播服務(wù),該服務(wù)可以在瀏覽器中通過flv.js進(jìn)行實時播放RTSP、RTMP和桌面投屏的畫面。我們將介紹所需的開發(fā)環(huán)境和依賴庫

    2024年01月20日
    瀏覽(34)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包