需要實現(xiàn)的功能:實時采集視頻和聲音,使用rtmp協(xié)議傳輸?shù)搅髅襟w服務器,流媒體使用的是開源的red5.基本實現(xiàn)思路:1、使用mediarecorder錄像,路徑設置為localsocket,這樣可以在socket中獲取實時視頻流。視頻格式設置的是H264,硬件是定制的,可以支持H264的硬編碼,所以獲取到的視頻流應該是編碼后的流。2、在網(wǎng)上找到了一個juv-rtmp-client的包,可以將編碼后的流通過rtmp協(xié)議發(fā)布到流媒體。3、在瀏覽器使用播放器播放實時視頻流。我找了一個開源的播放器,可以支持rtmp方式播放。現(xiàn)在遇到的問題:關于實時視頻,我還找到了一個IVideoChat的示例項目,但是他是使用的Camera的預覽回調獲取的實時視頻,關鍵代碼如下:
public void onPreviewFrame(byte[] arg0, Camera arg1)
{
// TODO Auto-generated method stub
if (!active)
return;
if (!init)
{
blockWidth = 32;
blockHeight = 32;
timeBetweenFrames = 100; // 1000 / frameRate
frameCounter = 0;
previous = null;
init = true;
}
final long ctime = System.currentTimeMillis();
byte[] current = RemoteUtil.decodeYUV420SP2RGB(arg0, width, height);
try
{
final byte[] packet = RemoteUtil.encode(current, previous,
blockWidth, blockHeight, width, height);
fireOnVideoData(new MediaDataByteArray(timeBetweenFrames,
new ByteArray(packet)));
previous = current;
if (++frameCounter % 10 == 0)
previous = null;
} catch (Exception e)
{
e.printStackTrace();
}
final int spent = (int) (System.currentTimeMillis() - ctime);
try
{
Log.i(TAG, "錕竭程等達拷" + Math.max(0, timeBetweenFrames - spent)
+ " s");
Thread.sleep(Math.max(0, timeBetweenFrames - spent));
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
其中,fireOnVideoData這個方法,就是將編碼后的視頻通過rtmp發(fā)布到流媒體了。使用這種方式,我可以在瀏覽器上看到正確的實時畫面,但是因為編碼效率太低,視頻很卡,并不實用。我要做的,就是將mediarecorder獲取到的H264視頻流處理一下,然后調用fireOnVideoData這個方法發(fā)布出去。關鍵代碼大概是這樣:
// 接收線程
Thread local_receive = new Thread()
{
public void run()
{
running = true;
try
{
is = mReceiveSocket.getInputStream();
byte buffer[] = new byte[4];
// Skip all atoms preceding mdat atom
while (true)
{
while (is.read() != 'm')
;
is.read(buffer, 0, 3);
if (buffer[0] == 'd' && buffer[1] == 'a'
&& buffer[2] == 't')
break;
}
byte[] current = new byte[10 * 1024];
while (running)
{
try
{
is.read(current);
fireOnVideoData(new MediaDataByteArray(
timeBetweenFrames, new ByteArray(current)));
} catch (Exception e)
{
e.printStackTrace();
}
}
} catch (IOException e)
{
Log.e(TAG, "Couldn't skip mp4 header :/");
return;
}
}
};
問題就出在這里了is.read(current);fireOnVideoData(new MediaDataByteArray(timeBetweenFrames, new ByteArray(current)));我通過is.read(current)讀取到視頻數(shù)據(jù)之后,直接調用下面的方法,肯定是有問題的。所以發(fā)布出去的視頻格式有問題,播不出來。我想請問一下,我應該如何處理這個視頻流呢?比如我應該怎么樣在讀取到的byte數(shù)組中,找出一幀數(shù)據(jù),可能再加上header獲取其他什么的,或者或者,哎呀我也不知道,蛋疼啊。另外,我找到了一個開源的視頻通話軟件源碼,spydroid,他的實現(xiàn)大概也是這樣的思路,只是他用的是rtsp協(xié)議,對視頻流處理的代碼沒看懂。。。。還請各位大神不吝賜教?。。。。≈x謝
聽起來,IVideoChat的實現(xiàn)是比較靠譜的,通過preview的方式獲得yuv格式的每一幀,然后壓縮成視頻格式發(fā)出去。
你的代碼里面,is.read讀取的是壓縮后的格式,如果想從這里面獲取到每一幀再轉化成你要的格式,至少應該先解碼吧,估計你還得用ffmpeg才能實現(xiàn)解碼。
所以呀,還是用IVideoChat的實現(xiàn)靠譜。
http://blog.csdn.net/mirage520/article/details/7038633 看一下這里是否可以參考,一直都想弄,也沒耐住心來搞這個
本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請
點擊舉報。