程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> J2me流媒體技術實現討論[1]

J2me流媒體技術實現討論[1]

編輯:關於JAVA

看到很多很多人持續在問這個問題。

以前我也聽說,好像kvm底層實現不太支持j2me來做streaming video/audio,但我不知道那人為什麼這麼說。

那麼現在國外有一個人提出下面這種思路,並且號稱在Nokia6260[相關數據:諾基亞 6260 Nokia62602.0 (3.0436.0) SymbianOS7.0s Series602.1 ProfileMIDP-2.0 ConfigurationCLDC-1.0]

上真實實現了(兩種網絡方式:藍牙和GPRS都試驗過),但我懷疑他的前提條件是“你的手機必須允許同時實現player的多個實例進入prefetched狀態(預讀取聲音流)”:

第一步:

聲明兩個Player;

第二步:

HttpConnection開始向服務器請求該audio文件的第一部分字節,我們定這次讀取的字節數為18KB;

第三步:

等第一部分數據到位後,Player A開始realize和prefetch,並開始播放;

第四步:

在Player A播放同時,(18KB的amr數據可以播放10秒鐘),HttpConnection繼續請求第二部分數據(假設GPRS每秒鐘傳輸3KB,那麼18KB需要傳輸6秒,算上前後通訊損失的時間,應該不會超過10秒鐘);

第五步:

第二部分數據到位後,假設Player A還沒有播放完(這需要調整你的每一部份數據字節數來使得假設成立),那麼將數據喂給Player B讓它realize和prefetch;

第六步:

Player A播放完後,得到事件通知,於是讓Player B開始播放。

如此往復。

大家看看此種理論可否。

我自己在nokia 7610上測試了一下,我上面說的前提被證明是可行的:“你的手機必須允許同時實現player的多個實例進入prefetched狀態(預讀取聲音流)”。真實Nokia手機確實可以如此:兩個線程中各自有一個Player,都開始做m_player.realize();和m_player.prefetch();,然後等候。

先播放線程1的Player,等她播放完後,通過

*
  * 本類實現了PlayerListener接口。通過這個事件來告知媒體已經播放完畢
  */
public void playerUpdate(Player player, String event, Object data){
  if(event == PlayerListener.END_OF_MEDIA){
   try{
    System.out.println("playerUpdate>>PlayerListener.END_OF_MEDIA");
    stopGauge();
    playForeground();
   }catch(Exception e){
    e.printStackTrace();
   }
  }
}

來通知第二個線程的Player播放。

這樣是可以的。

qinjiwy說“可以,不過前提是該音頻文件允許分段播放,有些音頻文件就是不允許的.”,你說得對。確實有很多格式的媒體文件不支持分段播放。我所知道的是wav可以,mp3也可以。

服務端每次只讀取這兩種媒體文件的某一部分,如果是mp3文件的話,我暫時不知道是否每次需要加上特殊的頭信息。

但是如果是WAV文件,那麼肯定每次都要加上WAV特定的頭,要不然Player也無法播放。

這種形式肯定是可行的。因為以前我在VC++上寫Text To Speech程序時,就是這麼做的:WAV文件的前若干個字節肯定是頭信息,這是一定的,隨後跟的全是RAW DATA;我每一次讀取WAV的RAW DATA若干字節後,傳給我的播放線程,他需要給這段RAW DATA前加上一個WAV HEADER,然後就可以正常播放了。

Server side java code:

public void transfer(DataOutputStream output) {
         try{  
                   int i = 0;
                   int auglis = 50058; //chunk size
                //if it is wav file, we need to edit header:
                   //audio[4] = (byte)0x8A;
                   //     audio[5] = (byte)0xC3;
                  //  audio[6] = (byte)0x00;
                  //  audio[7] = (byte)0x00;
                  
                   //  audio[54] = (byte)0x50;
                  //  audio[55] = (byte)0xC3;
                  // audio[56] = (byte)0x00;
                  // audio[57] = (byte)0x00;
                   byte[] tmp = new byte[50058];
                   int countBytes= 0;
                   int headerup = 32; //mp3 header is 32 bytes.
                while(i<50058){
                 tmp[i] = audio[i]; //byte array audio is byte array from mp3 file
                 i++;
                 countBytes++;
                   }  
                output.writeInt(50058);     //write to midlet, that chunk size will be 50058
                output.write(tmp);   //write chunk itself
                   boolean varam = true; //booleand that will become false, when file ends
                   while(varam){
                   int tmplen = garums - countBytes; //check if it is not last chunk
                   int o=50058;
                   if(tmplen>50058){ //if it is not last chunk
                     o = 50058;  
                   }
                   else{
                   o = tmplen+headerup; // if it is last chunk
                   tmp = new byte[o];
                   varam = false; //out while loop will end
                   }
                       int z = 0;
                       while(z<32){ //write 32 byte header to chunk
                       tmp[z] = audio[z];          
                       z++;
                       countBytes++;
                       }   
                       while(z<o){ //white chunk it self
                       tmp[z] = audio[i];
                       z++;
                       i++;
                       countBytes++;
                       }  
                          
                  headerup =  headerup +32;
                  output.writeInt(o);          //white size of chunk (typically 50058)
                  output.write(tmp);    //white chunk itself
                   }
         }
         catch (Exception e) {}
    }
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved