【視訊採集方案】
Android視訊採集,傳輸,編碼解碼的方案總結
-
ipcamera-for-android
伺服器 : Android手機充當伺服器,使用NanoHTTPD充當伺服器
客戶端 : 手機或者pc輸入http://server ip:8080觀看。
缺點: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個位元組
- buffer[0] = (byte) Integer.parseInt("10000000",2);
M:標記一些重要的事件(由應用程式定義); 佔1個bit
PT:淨荷資料型別; Payload Type,佔7個bit
- java程式碼表示,buffer[1]表示rtp包的第1個位元組
- buffer[1] = (byte) 96;
相關推薦
【視訊採集方案】
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