1. 程式人生 > >【視訊採集方案】

【視訊採集方案】

Android視訊採集,傳輸,編碼解碼的方案總結
  1.  ipcamera-for-android

伺服器 :    Android手機充當伺服器,使用NanoHTTPD充當伺服器

客戶端 : 手機或者pc輸入http://server ip:8080觀看。

pcdevice

缺點:android手機必須支援MP4+ARM_BN格式,有些手機不相容,延時有點厲害,而且用到NDK程式設計,現在看來方案不可取

現在似乎有個更新的版本,專案名字:android-eye-master

需要的可以百度或者留言, 不過還是用camera類採集視訊流。

2 .  ivideochat

伺服器 :   通過rtmp協議釋出服務到red5伺服器,可用red5自帶的的OFLA Demo測試.

客戶端 : Android手機採用juv-rtmp-client.jar包,網上有破解的收費包。

播放端  :  使用支援rtmp協議的播放器播放,如ffplay,vlc,ffmpeg等.

伺服器當然是red5了,可以用red5自帶的的OFLA Demo做測試.

缺點:demo延遲很厲害,僅供參考。rtmp協議半公開,難度比較大

3. Camera  and  Socket

通過Camera拍攝預覽中設定setPreviewCallback實現onPreviewFrame介面,實時擷取每一幀視訊流資料 .  把一幀一幀的影象壓縮通過socket傳送到伺服器,伺服器可以直接觀看。而要想讓另一臺手機也能觀看,可以讓伺服器轉發來實現。

伺服器 :    Android手機通過camera類拍攝視訊,把一幀一幀的影象壓縮通過socket發 送到伺服器,伺服器可以直接觀看

客戶端 : 要想讓另一臺手機也能觀看,可以讓伺服器轉發來實現。

缺點:  通過一幀一幀的傳送資料,傳輸過程耗費大量流量。玩玩可以,但實際專案 中不可取。

4.  流媒體伺服器方式:ffmpeg或Getstreamer等獲取Camera視訊 

android手機通過camera類拍攝視訊,把拍攝的視訊通過h264編碼,可以採用軟編碼(使用x264庫或者opencore軟體庫),java類通過jni呼叫編譯後的so檔案來實現。然後通過基於udp的rtp協議傳輸到伺服器。為什麼不使用tcp協議呢,因為tcp的重傳機制會產生延時和抖動,而單獨使用udp傳輸協議本身是面向無連線的,不能提供質量保證,需要在udp協議只上採用rtp或者rtcp提供流量控制和擁塞控制服務。伺服器通過ffmpeg對接收的h264解碼並播放。播放可以使用VLC media player。如果對c++比較熟悉,可以看看live555這個開源專案。

缺點:需要懂得的知識很多,jni啊,h264編碼解碼 ,rtp協議等。使用軟編碼,效率比較低,且視訊質量較差。

5. MediaRecorder+h264

通過Andoriod的MediaRecorder,在SetoutputFile函式中繫結LocalSocket實現 .

android手機通過mediaRecorder類拍攝視訊,其中當然包括音訊了。把拍攝的視訊通過h264編碼,可以採用硬編碼(面向手機的硬體直接操作),只能針對3gp,mp4視訊格式。

這篇部落格,裡面講的很詳細,提取h264的sps,pps,可以參考

程式碼網上有很多,個人理解是:mediaRecorder錄製視訊(3gp,MP4),可以通過mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());預覽視訊,通過localsocket傳送到本地的localserversocket的h264實時視訊流。

這個過程涉及到硬編碼,硬編碼個人理解是,在預覽過程或者提前確定視訊的sps,pps,head(一般為0x00000001),不同的手機硬體不一樣。把得到的這些引數寫入h264,得到正確的h264視訊流,然後把流推送到流媒體伺服器,使用支援rtsp協議的播放器播放,比如vlc.

6、採用HLS協議,伺服器採用nginx,ffmpeg解碼。nginx伺服器搭建過程,ffmpeg安裝過程  見我前幾篇文章。

然後用ffmpeg對解碼後的mp4檔案進行ts切片,生成帶有索引的m3u8檔案,然後客戶端就可以通過瀏覽器http://ip :port/ *.m3u8訪問。

過程貌似是這樣的,但自己由於剛接觸不到一個周,還不太理解。

7. smartcam的一個開源專案,看了下原始碼,發現其實現原理是利用Android 的camera影象的預採集,通過實現PreviewCallback類的回撥函式onPreviewFrame,獲得camera採集的原始影象資料之後,壓成jpeg格式傳到pc端。pc端對接收到的jpeg影象序列進行實時解壓和顯示,就達到了預想的效果。

雖然這種方式稍微顯得比較笨拙,這個方式還可以接受。但是不可接受的是jpeg只是幀內壓縮,320x280的圖片序列,FPS大概是10上下,網路流量就到達了100kb/s以上。這個幾乎是無法實際應用的。

於是必須直接傳視訊流,MPEG4或者H.264格式。貌似我的開發機上(HTC G8)只支援到MPEG4,所以還是選取MPEG4。但是如何實時採集視訊流是一個大問題,畢竟在video方面,Android並沒有提供一個類似於OnPreviewFrame的回撥函式。

想到用opencore或者更為新一點的stagefright,大概看看了其sdk的框架後,馬上洩氣了,這個太龐大了。在http://www.linuxidc.com/Linux/2011-04/34468.htm的帖子中提到一個很好的解決方案,就是利用MediaRecorder:MediaRecorder的輸出路徑(其實叫file descriptor)除了是本地檔案路徑之外,還可以繫結socket埠。也就是說,通過一個socket埠,就可以實時獲得MediaRecorder的視訊流資料。

6. spydroid -MediaRecorder

相對容易、且效果不錯的方法,android手機上搭建rtsp伺服器,另一臺手機使用      VLC播放器輸入rtsp://ip:port/播放視訊。具體原理是,通過android手機對mediaRecorder錄製視訊,把localsocket傳輸到本地的流經過硬編碼,新增rtp頭,分離NALU包,根據rtsp協議互動過程把資料傳送到對方。

程式碼參考spydroid了,原始碼可以通過svncheckout,能夠正常執行,且效果不錯。

網上還沒有分析spydroid原始碼的文章,等自己空了有機會分析下原始碼。

7.  前面講的都是單向視訊,如果是雙向視訊,其實就是視訊會議了,可以參考開原始碼了

Libstreaming是一個開源的流媒體框架,它可以讓手機變成一臺流媒體伺服器,直接在PC端檢視手機攝像頭的實時畫面。值得一提的是它的作者也是spydroid的作者。按照作者的說法,spydroid是利用該庫完成流媒體傳輸的,但據筆者的分析觀察,此說法並不十分確切。Libstreaming是spydroid的抽象與昇華,RTSP伺服器的實現方式也有很大的不同。

巧婦難為無米之炊,我們先把Libstreaming的原始碼下載下來。地址:https://github.com/fyhertz/libstreaming 下載完畢後匯入eclipse,並新建工程引用該庫。這裡要頗為注意,新建的工程必須和Libstreaming在同一個碟符下,否則可能出現引用失敗的問題。

接下來看看官方文件中給出的建立RTSP伺服器的步驟:

1、Add this to your manifest:

<service android:name="net.majorkernelpanic.streaming.rtsp.RtspServer"/>

把RtspServer這個服務在androidManifest檔案中進行註冊。在libstreaming庫中,rtsp伺服器是作為service組建實現的,這與spydroid的實現方式完全不一樣。

2、You can change the port used by the RtspServer:

Editor editor = PreferenceManager.getDefaultSharedPreferences(this).edit();
editor.putString(RtspServer.KEY_PORT, String.valueOf(1234));
editor.commit();

The port is indeed stored as a String in the preferences, there is a good reason to that. The EditTextPreference object saves its input as a String and cannot easily (one would need to override it) be configured to store it as an Integer.

可以改變rtsp伺服器的埠,當然,這是非必需的。預設埠是8086。若想改變埠,必須通過sharedPreference完成。先獲取一個指向本activity的sharedPreference的editor物件,再將指定的埠號put進去。至於為什麼用String型別而不是用整形儲存埠號,主要是考慮到EditTextPreference物件的儲存型別是string。

3、Configure its behavior with the SessionBuilder:

SessionBuilder.getInstance()    
            .setSurfaceHolder(mSurfaceView.getHolder())
            .setContext(getApplicationContext())
            .setAudioEncoder(SessionBuilder.AUDIO_AAC)
            .setVideoEncoder(SessionBuilder.VIDEO_H264);

sessionBuilder是session的建造者。而session又是伺服器與客戶端間通訊的載體。此部分主要是設定sessionBuilder的一些選項,如音訊編碼器、視訊編碼器等等。注意,sessionBuilder用到了單例設計模式,整個程式共享這一個sessionBuilder物件。此外,值得一提的是sessionBuilder的setSurfaceHolder方法,此方法其實沒有太大的用處,不過因為android 某些API的限制,使得如果你要錄製視訊,必須要有有效的surface。

5、Start and stop the server like this:

// Starts the RTSP server
context.startService(new Intent(this,RtspServer.class));
// Stops the RTSP server
context.stopService(new Intent(this,RtspServer.class));

最後,啟動或停止service。

完整的示例:

1、佈局檔案——activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >  
    <SurfaceView 
        android:id="@+id/surface"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</RelativeLayout>

2、程式碼——MainActivity.java

package com.dyc.spydroidrtspserver;

import net.majorkernelpanic.streaming.SessionBuilder;
import net.majorkernelpanic.streaming.rtsp.RtspServer;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences.Editor;
import android.view.Menu;
import android.view.SurfaceView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
	SurfaceView surfaceView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);//載入佈局
		surfaceView=(SurfaceView)findViewById(R.id.surface);
		Editor editor=PreferenceManager.getDefaultSharedPreferences(this).edit();//獲取sharedPreference的editor物件
		editor.putString(RtspServer.KEY_PORT, "1234");//將新的埠號put進去
		editor.commit();//提交更改
		SessionBuilder.getInstance()
		.setAudioEncoder(SessionBuilder.AUDIO_AMRNB)
		.setVideoEncoder(SessionBuilder.VIDEO_H264).
		setContext(getApplicationContext()).
		setSurfaceHolder(surfaceView.getHolder());//配置sessionBuilder物件
		this.startService(new Intent(this, RtspServer.class));//啟動服務
		displayIpAddress();//顯示地址
	}
	private void displayIpAddress() {
		WifiManager wifiManager=(WifiManager)getSystemService(Context.WIFI_SERVICE);
		WifiInfo wifiInfo=wifiManager.getConnectionInfo();
		int address=wifiInfo.getIpAddress();//獲取IP地址,注意獲取的結果是整數
		Toast.makeText(this, "rtsp://"+intToIp(address)+":1234", Toast.LENGTH_LONG).show();//用toast列印地址
		
	}
	private String intToIp(int i)  {//整形轉IP
		return (i & 0xFF)+ "." + ((i >> 8 ) & 0xFF)+ "." + ((i >> 16 ) & 0xFF) +"."+((i >> 24 ) & 0xFF );
		}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}

3、androidManifest檔案

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.dyc.spydroidrtspserver"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.dyc.spydroidrtspserver.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name="net.majorkernelpanic.streaming.rtsp.RtspServer" />
    </application>

</manifest>

我這裡只是一個簡單的演示 ,所以沒有判斷到底有沒有用wifi。它官方有給示例,詳見:https://github.com/fyhertz/libstreaming-examples 可以去看一下

spydroid原始碼分析(一):介紹spydroid每個包的大體功能

看了接近一週的spydroid原始碼,對spydroid這個開源專案有了一定的認識。也許有些理解不一定正確,給後來者一點啟示。也是自己對rtsp協議,rtp協議的總結。

在windows下,如果安裝了svn,可以通過      svn checkout http://spydroid-ipcamera.googlecode.com/svn/  下載原始碼,最新原始碼是spydroid6.7.1

下載後,匯入eclipse工程,直接就可以編譯執行。

在這裡只關心其src原始碼部分,其他地方都比較簡單,就不介紹了。src原始碼有以下幾個package。

net.majorkernelpanic.http主要是介紹http server,spydroid自身內建http伺服器,客戶端可以通過在VLC等播放器中輸入http://ip:8080/播放

net.majorkernelpanic.mp4主要是介紹提取mp4檔案的profile,sps,pps等資訊

net.majorkernelpanic.networking 主要是介紹rtsp伺服器部分,spydroid自身內建rtsp伺服器,客戶端可以通過在VLC等播放器中輸入rtsp://ip:8086/播放

net.majorkernelpanic.rtp主要是介紹rtp協議通訊

net.majorkernelpanic.spydroid主要是activity的介面部分。

net.majorkernelpanic.streaming主要是stream介面和抽象類

net.majorkernelpanic.streaming.audio介紹音訊部分

net.majorkernelpanic.streaming.video介紹視訊部分

以後針對mp4,networking ,rtp,stream這4個包的內容重點分析

未完待續

這幾天空閒的時候在看《struts2技術內幕》這本書,作者downpour說的這句話我很贊同,忘了原文了,  學習開源專案,不是一個包一個包的閱讀程式碼,而是通過動態執行專案,通過斷點除錯,來獲取相關資訊。 我也打算用這種方式來看spydroid原始碼,但瞭解每個package大體的功能是必須的。

如果spydroid已經安裝到了android手機上,開啟這個軟體,VLC就可以通過rtsp://手機的ip:8086/訪問。在這裡以H264來說明spydroid的執行流程,其他類似。在這裡需要吧option的encode編碼設為h264.除錯android原始碼,可以通過logcat列印相關資訊

程式執行時,進入net.majorkernelpanic.spydroid.SpydroidActivity,該activity 執行時候,開啟http server ,rtsp server。這裡重點關注rtsp 服務。

   進入  net.majorkernelpanic.networking.RtspServer

rtspserver開啟後,啟動一個執行緒RequestListenerThread,負責監聽客戶端(這裡用VLC)的請求,public void start() throws IOException {
if (running) return;
running = true;
listenerThread = new RequestListenerThread(port,handler);
listenerThread.start();
}
當有客戶端請求的時候,開啟一個workerTread執行緒。一個執行緒session代表一個請求

	new WorkerThread(server.accept(), handler).start();

VLC向rtsp伺服器進行互動時,這裡就需要用到rtsp協議的內容了,主要分為Options,Describe,Setup,play,teardown這5步驟。

下面是我進行rtsp連線,伺服器與客戶端請求與響應的詳細資訊,

//當來自192.168.1.26的VLC客戶端向手機伺服器傳送rtsp://192.168.1.60:8086請求時

Connection from 192.168.1.26        //來自192.168.1.26的請求

//下面的C表示客戶端client,S表示伺服器server
C-S:OPTIONS rtsp://192.168.1.60:8086/ RTSP/1.0     //可用選項
S-C: Public: DESCRIBE,SETUP,TEARDOWN,PLAY,PAUSE        //描述資訊、建立連線、關閉、播放、暫停

C-S:DESCRIBE rtsp://192.168.1.60:8086/ RTSP/1.0
S-C:
v=0
o=- 1357627796453 1357627796453 IN IP4 192.168.1.60      //1357627796453是當前的timestamp資訊,timestamp =System.currentTimeMillis();
s=Unnamed
i=N/A
c=IN IP4 192.168.1.26
t=0 0            //t=0 0意味著會話是永久的
a=recvonly
m=video 5006 RTP/AVP 96    //video指明是視訊資訊, 5006是指客戶端VLC接收視訊資訊的udp埠號

b=RR:0
a=rtpmap:96 H264/90000          //這裡的96的資訊很關鍵,因為這個是rtp的負載型別,Payload type (PT): 7 bits。後面介紹rtp協議的時候會介紹,H264編碼,90000是H264視訊傳輸的預設視訊取樣頻率,必須是這個值
a=fmtp:96 packetization-mode=1;profile-level-id=42c016;sprop-parameter-sets=ZOLAFukBQHsg,aM4G4g==;</             //packetization-mode=1指定rtp打包模式,有3種模式,數值只能為0,1,2,。0是單NAL單元模式 1是非互動模式 2是互動模式
profile,sps,pps這3個數值是從mp4中提取出來的base64編碼,在net.majorkernelpanic.mp4這個包      有詳細介紹。a=control:trackID=0   //trackID為0

Content-Base: 192.168.1.60:8086/
Content-Type: application/sdp          //規定檔案格式型別為sdp

C-S:SETUP 192.168.1.60:8086/trackID=0 RTSP/1.0
S-C:
Transport: RTP/AVP/UDP;unicast;destination=192.168.1.26;client_port=5006-5007;server_port=49749-49750;ssrc=431567f7;mode=play
Session: 1185d20035702ca        //制定基於udp協議的rtp傳輸,目標地址,客戶端埠、伺服器埠,以及ssrc的數值,這裡ssrc的數值很重要,它是同步源標識,synchronization source (SSRC) identifier,在rtp傳輸中,會包含這個內容
Cache-Control: no-cache

C-S:  PLAY 192.168.1.60:8086/ RTSP/1.0
S-C:
RTP-Info: url=rtsp://192.168.1.60:8086/trackID=0;seq=0
Session: 1185d20035702ca       //session標識

C-S:   TEARDOWN 192.168.1.60:8086/ RTSP/1.0

在上面的內容中,可以看到options請求時,傳送可用的狀態。
describe請求時,傳送流型別,在這裡是h264視訊流,以及mp4 的profile,sps,pps,在不同手機上,profile,sps,pps的數值不一定相同。這個是通過提取錄製的該手機上的mp4檔案的內容得到的。 除了H264,這裡也可以是H263視訊流,或者其他audio音訊流。這裡重點檢視generateSessionDescriptor()   方法,比如在這裡,選擇H264,那麼就可以看看H264Stream這個類的這個方法,看看它是如何獲取profile ,sps,pps的setup請求時,主要關注stream.prepare(),stream.start()方法,prepare()的時候呼叫初始化視訊錄製的引數,比如H264編碼,解析度,幀數等相關資訊。而start()方法就開始通過localsocket把錄製的視訊以流的形式傳送到本地,而H264Packetizer通過獲取其輸入流,然後對其rtp打包處理,傳送。

寫完後才發現排版極為糟糕,重新整理一下

網上有很多的rtp協議介紹的文章,我也老生常談的拿來使用了,

先介紹rtp包頭,我們都知道,rtp包頭佔12個位元組,1個位元組byte當然是8個bit了,下面是詳細介紹。看下面的這張圖

V:版本號;        Version(2),佔2個bit,數值為2,二進位制表示10

P:填充欄位標識; Padding(0),佔1個 bit,數值為0,二進位制表示0

X:擴充套件頭標識;      Extension(0),佔1個bit ,數值為0,二進位制表示0

CSRC count(CC):貢獻源數目,和後面的CSRC有關。CSRC,貢獻源,指的是不同步的源。在網路中,可能會有混合器將來自不同地點的RTP流混合成一個RTP流以節省頻寬, CSRC用來區分不同的源;  Source Identifier(0),佔4個bit,數值為0,二進位制表示為0000

java程式碼表示,buffer[0]當然是指的是rtp包的第0個位元組

  1. buffer[0] = (byte) Integer.parseInt("10000000",2);

M:標記一些重要的事件(由應用程式定義);  佔1個bit

PT:淨荷資料型別; Payload Type,佔7個bit

  1. java程式碼表示,buffer[1]表示rtp包的第1個位元組
  1. buffer[1] = (byte96;

相關推薦

視訊採集方案

Android視訊採集,傳輸,編碼解碼的方案總結  ipcamera-for-android 伺服器 :    Android手機充當伺服器,使用NanoHTTPD充當伺服器 客戶端 : 手機或者pc輸入http://server ip:

視訊免費分享基於Spring Boot技術棧 部落格系統企業級前後端實戰

推薦視訊連結 Java 微服務實踐視訊教程 - Spring Boot Java 微服務實踐 視訊教程- Spring Cloud redis高可用視訊 分散式電商商城視訊教程 kubernets+docer jvm 秒殺專案實戰 Lin

問題解決方案原生代碼檔案上傳到GitHub裡中文亂碼問題

剛剛學完Git並試著上傳了我的化石Java程式碼到遠端庫,表面一切和諧,然而。。 真讓人大驚失色。。 step1-檢查瀏覽器是否是utf-8(谷歌預設是) step2-在本地編輯器設定 (按理說,notepad好像可以,但是畢老師用的editplus,我強迫症要保持一致。。) 此處說一下edit

問題解決方案editplus中批量將ANSI轉換為utf-8

來自一個用editplus寫java程式但是上傳到GitHub裡中文亂碼的故事 大致步驟: editplus全部開啟之後(開啟為何種編碼不重要): (全部開啟是指在左下方的檔案列表選中-->右擊-->開啟) 1-選文件(Document)選單 2-檔案編碼(File encoding)

視訊直播錄製Boinx mimoLive for Mac破解版

Boinx mimoLive for Mac是一款非常優秀的視訊實時錄製直播工具.mimoLive Mac破解版能夠用於電視廣播,視訊直播,學校電視,視訊投影.mimoLive Mac版功能強大,使用簡單,能夠讓您的Mac變成一個電視演播廳!有需要的朋友快來看看吧! Boinx mimoLive

視訊播放器potplayer調教教程

Potplayer基礎調教教程 一、設定相關 1.0 基本 最前端方式:不使用最前端功能 這個就是設定介面是否總在最前,全屏時狀態列不自動隱藏不建議在這裡設定 相似檔案策略:同時開啟全部檔案 即開啟一個檔案時把同文件夾下的其他支援的檔案也新增到播放列

問題解決方案Dev C++ 無法除錯的問題與解決

聽翁愷老師課的時候用到一個叫DevC++的編輯器。 學到除錯部分的時候,老師的沒問題我的報錯。我?? 試一試網上查到的方法: 工具 --> 編譯選項 --> 程式碼生成/優化 --> 聯結器 --> 產生除錯資訊:改成yes (第二步:編譯不是編輯器選項) 可以了

前端解決方案input file 上傳圖片,並實現實時預覽

前言 我最近在做自己個人部落格的時候,遇到一個前端的問題,就是如何實時預覽 input 標籤上傳的圖片。一般的 <input type="file’ /> 標籤是不能實現實時預覽的。 解決方案 可以通過 file 標籤和 js 的 FileReader 介面來實

Android實時視訊採集方案

實時視訊流採集 方案一:  通過Android Camera拍攝預覽中設定setPreviewCallback實現onPreviewFrame介面,實時擷取每一幀視訊流資料  方案二:  通過Android的MediaRecorder,在SetoutputFile函式中繫結

視訊處理工程4、DirectShow基本開發過程(二)

前文講了一些開發DirectShow的基本配置方法以及一些基本的開發過程,如如何創造一個filter並加入filter graph中。這裡繼續上文的步驟討論如何得到filter的pin,以及如何連線兩個filter。 1、如何獲取filter的pin 獲取filter上的p

iOS解決方案網路請求返回GB2312格式的xml資料轉成UTF-8後為空(適用於論壇bbs)

一些高校的bbs由於歷史久遠,沒有適應新的資料結構,請求返回的資料還是xml格式的,而現在常用的返回是json,這是個很頭疼的地方,碰到的問題網上很難搜到資料,走了很多彎路。 現在具體講一下在解析返回xml過程中碰到的問題,希望能有些借鑑: 1.xml編碼問題: 對

視訊處理工程6、使用Lav Filter手動建立Filter Graph並播放視訊檔案

在前面的這篇博文中,我們開始利用的手動建立Filter Graph,已經完成了Splitter Source Filter和Audio/Video Decoder的建立和連結。接下來需要做的是渲染解

問題解決方案從 Anaconda Prompt 或 Jupyter Notebook 終端進入Python後重新退出到命令狀態

-c 退出 bubuko 終端 問題解決 技術分享 jupyter img python3.5 從 Anaconda Prompt 或 Jupyter Notebook 終端進入Python後重新退出到命令狀態 退出Python:exit() 或者 Ctrl+z 例子一枚

問題解決方案ImportError: No module named 'openpyxl'/‘xlrd’

exc matplot bubuko libc .com png err 安裝 ror 背景: 在jupyter notebook to_excle: 運行將dataframe保存為excel文件 df.to_excel(‘dataframe.xlsx‘) 時報錯openp

問題解決方案Keras手寫數字識別-ConnectionResetError: [WinError 10054] 遠程主機強迫關閉了一個現有的連接

遠程主機 googl reset info 識別 .cn keras com demo 參考:臺大李宏毅老師視頻課程-Keras-Demo 在載入數據階段報錯: ConnectionResetError: [WinError 10054] 遠程主機強迫關閉了一個現有的連接

問題解決方案git/github本地和遠程倉庫的重命名

顯示 目錄 png 技術分享 路徑 tps code 只有一個 mage 終於看到一條規範裏寫著: “通常(註意是通常,尤其是 Web 相關的項目) repo 的命名用小寫英文,多個字母之間用連字符(比如 react-native)” 參考自知乎:GitHub 上開源一個

問題解決方案知乎某個答案的鏈接在哪裏的問題

單個 hub 參考 image 測試 網頁版 在哪裏 https 問題 參考: 知乎回答:如何貼出單個知乎答案的網址? 使用背景: 在博客或者github中貼參考文檔鏈接,有時用到知乎某個問題 那麽問題來了,網頁版中單個問題的鏈接很好找,單個回答的鏈接在哪裏呢 解鈴

問題解決方案anaconda-python在cmd-pip安裝requests後依然提示No module named requests

-i alt python3.5 第一個 文件 解決方案 測試 問題 方法 參考: 知乎回答:python的requests安裝後idle依然提示No module named requests? 環境: win7-64位 anaconda3-Python3.7 &a

成熟方案新港海岸NCS8803:HDMI轉EDP視訊轉換晶片方案

3.2、NCS8803 3.2.1 功能:是一顆將HDMI訊號轉EDP訊號的轉接晶片。其應用如下: 3.2.2產品特徵 輸入:HDMI 輸出:Embedded-DisplayPort (eDP) EDP介面 1/2/4-lane eDP @ 1.62/2.7Gbps per l

成熟方案新港海岸NCS8801S:RGB/LVDS轉EDP視訊轉換晶片方案

3、新港海岸 3.1、NCS8801S 3.1.1 功能:NCS8801S是一顆將LVDS/RGB訊號轉換成EDP訊號的轉接晶片,其應用圖如下: 3.1.2產品特徵: 輸入:Single/Dual link LVDS/RGB 輸出:EDP EDP介面: 1/2/4-lane