2014-01-16 22 views
2

我正在使用PHP開發的一個寧靜的web服務。 Web服務將發送數據圖像。對於圖片,它會發送圖片名稱,我們將準備圖片的網址以便下載。但現在需要下載視頻文件。我們可以像下載圖像一樣遵循相同的方式(例如:image name =「myimage1.jpeg」url = www.xyz.com/images/myimage1.jpeg「,我們將直接讀取並在本地創建文件),但想知道有從PHP任何方式從PHP發送類似二進制字符串的數據,並將其轉換成電影文件在Android的結束。如何發送視頻文件作爲json數據。 (不是文件名或路徑,但內容)Android

(我們可以將圖像發送的JSON數據從PHP Web服務,請給一些代碼)

注意:如何發送圖像/視頻文件從RESTful Web服務的JSON數據

+5

可能在理論上,但您需要傳輸的數據量會爆炸。這將需要很長時間!但是如果你仍然想嘗試一下 - 看看Base64。 – cwin

+0

這是一個非常糟糕的主意,因爲數據必須完全傳輸,然後才能對其執行任何操作。不要「流式傳輸」視頻,您需要先下載它,然後才能開始展示它。 – ayckoster

+0

將視頻數據嵌入到JSON中時,您會有什麼好處? – Sven

回答

0
import java.io.File; 

import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.PathParam; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.Response; 
import javax.ws.rs.core.Response.ResponseBuilder; 
import javax.ws.rs.core.Response.Status; 

@Path("/file") 
public class DownloadVideoREST { 

    private static final String VIDEO_FILE = "E:\\xyz.flv"; 


    @GET 
    @Path("/video") 
    @Produces("video/flv") 
    public Response getVideoFile() { 

     File file = new File(VIDEO_FILE); 

     ResponseBuilder response = Response.ok((Object) file); 
     response.header("Content-Disposition", "attachment; filename=\"abc.flv\""); 
     return response.build(); 

    } 



     @GET 
     @Path("/{fileName}/video") 
     @Produces("video/flv") 
     public Response getFileInVideoFormat(@PathParam("fileName") String fileName) 
     { 
      System.out.println("File requested is : " + fileName); 


      if(fileName == null || fileName.isEmpty()) 
      { 
       ResponseBuilder response = Response.status(Status.BAD_REQUEST); 
       return response.build(); 
      } 


      File file = new File("c:/abc.flv"); 

      ResponseBuilder response = Response.ok((Object) file); 
      response.header("Content-Disposition", "attachment; filename=abc.flv"); 
      return response.build(); 
     } 
} 
3

由於ChriZzZ說,這是不可取的(而不是真正的原生支持)的JSON

但是,您可以考慮使用BSON (Binary JSON)。特別是對於PHP實現,該網站提供了一個鏈接到Mongo,所以你可能想檢查一下。不幸的是,我沒有代碼可以提供。

0

這裏是根據PHP官方文檔的信息。 希望它可以用於視頻文件。

 HttpClient client = new DefaultHttpClient(); 
     HttpPost post = new HttpPost(serverURL); 
     MultipartEntity postEntity = new MultipartEntity(); 
     File file = new File("file path to be put here"); 
     postEntity.addPart("fileupload", new FileBody(file, "video/mp4")); 
     postEntity.addPart("loginKey", new StringBody(""+loginKey)); 
     postEntity.addPart("message", new StringBody(message)); 
     postEntity.addPart("token", new StringBody(token)); 
     post.setEntity(postEntity); 
     response = client.execute(post); 
+0

如果有效,那麼不要忘記將答案標記爲已接受。 – gargAman

+0

此代碼用於將圖像上傳到服務器。我的要求是通過PHP webservice發送圖像/視頻。事實上,你有一個點上面。但是,以JSON格式發送數據爲webservice的問題(可以是任何東西) – kumar

0

試試這個對你有用。

HttpClient httpclient = new DefaultHttpClient(); 
    HttpPost httppost = new HttpPost(URL);// 
    FileBody filebodyVideo = new FileBody(file); 
    StringBody title = new StringBody("Filename: " + filename); 
    MultipartEntity reqEntity = new MultipartEntity(); 
    reqEntity.addPart("videoFile", filebodyVideo); 
    httppost.setEntity(reqEntity); 
    HttpResponse response = httpclient.execute(httppost); 
0

爲什麼不是你接收視頻的文件路徑在你的web服務,而不是在web服務整個視頻音頻文件,如接收整個文件的大小限制的情況下,可以exceded,您將收到無效JSON響應PHP。因此,它更安全地檢索服務器上的視頻文件路徑,而不是視頻本身作爲響應。

另一種方法是你使用webview並把下載鏈接作爲在下載視頻文件的情況下。

0

這可能對你有幫助:

PHP代碼(video.php)

<?php 

if(isset($_GET['name'])) 
{ 
$video_name = $_GET['name']; 
$path = "/path/to/videos/folder/$video_name"; //ex: video.mp4 

$size=filesize($path); 

[email protected]($path,'rb'); 
if(!$fm) { 
    // You can also redirect here 
    header ("HTTP/1.0 404 Not Found"); 
    die(); 
} 

$begin=0; 
$end=$size; 

if(isset($_SERVER['HTTP_RANGE'])) { 
    if(preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)) { 
    $begin=intval($matches[0]); 
    if(!empty($matches[1])) { 
     $end=intval($matches[1]); 
    } 
    } 
} 

if($begin>0||$end<$size) 
    header('HTTP/1.0 206 Partial Content'); 
else 
    header('HTTP/1.0 200 OK'); 

header("Content-Type: video/mp4"); 
header('Accept-Ranges: bytes'); 
header('Content-Length:'.($end-$begin)); 
header("Content-Disposition: inline;"); 
header("Content-Range: bytes $begin-$end/$size"); 
header("Content-Transfer-Encoding: binary\n"); 
header('Connection: close'); 

$cur=$begin; 
fseek($fm,$begin,0); 

while(!feof($fm)&&$cur<$end&&(connection_status()==0)) 
{ print fread($fm,min(1024*16,$end-$cur)); 
    $cur+=1024*16; 
    usleep(1000); 
} 
die(); 
}else{ 
    echo "Please provide a Video name (name=)"; 
} 
?> 

的Java代碼(下載並保存視頻到SD卡):

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.InputStream; 
import java.net.HttpURLConnection; 
import java.net.URL; 
import android.content.Intent; 
import android.os.AsyncTask; 
import android.os.Environment; 
import android.util.Log; 


public class VideoSaveSDCARD extends Activity{ 

public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     ProgressBack PB = new ProgressBack(); 
     PB.execute(""); 
    } 

    class ProgressBack extends AsyncTask<String,String,String> { 
     ProgressDialog PD; 
     @Override 
     protected void onPreExecute() { 
      PD= ProgressDialog.show(LoginPage.this,null, "Please Wait ...", true); 
      PD.setCancelable(true); 
     } 

     @Override 
     protected void doInBackground(String... arg0) { 
     DownloadFile("http://yourserver/video.php?name=video.mp4","video.mp4");    

     } 
     protected void onPostExecute(Boolean result) { 
      PD.dismiss(); 

     } 

    } 



    public void DownloadFile(String fileURL, String fileName) { 
     try { 
      String RootDir = Environment.getExternalStorageDirectory() 
        + File.separator + "Video"; 
      File RootFile = new File(RootDir); 
      RootFile.mkdir(); 
      // File root = Environment.getExternalStorageDirectory(); 
      URL u = new URL(fileURL); 
      HttpURLConnection c = (HttpURLConnection) u.openConnection(); 
      c.setRequestMethod("GET"); 
      c.setDoOutput(true); 
      c.connect(); 
      FileOutputStream f = new FileOutputStream(new File(RootFile, 
        fileName)); 
      InputStream in = c.getInputStream(); 
      byte[] buffer = new byte[1024]; 
      int len1 = 0; 

      while ((len1 = in.read(buffer)) > 0) {       
       f.write(buffer, 0, len1);    
      }  
      f.close(); 


     } catch (Exception e) { 

      Log.d("Error....", e.toString()); 
     } 

    } 


} 
+0

這是正常的做法。這就是我們正在做的。但我在尋找的是,有沒有什麼辦法可以將圖像/視頻作爲json數據本身的一部分發送(不僅僅是圖像/視頻的名稱)。非常感謝你。 – kumar

1

當然你可以用JSON發送視頻數據,但是由於JSON本質上是一個字符串格式,有幾個保留字符你將不得不編碼視頻數據。 你可以使用任何你喜歡的方案 - 但BASE64是一個被廣泛接受的標準,所以我會使用它。

只需創建一個JSON字符串對象並用BASE-64編碼的視頻數據填充它即可。

但要小心緩衝區溢出!!!由於許多JSON實現通常不會期望JSON中的巨大數據元素,因此可以建議將數據流分成幾個較小的塊並一次提交一個塊......當然,您也可以只傳輸JSON數據本身,但據我所知,大多數JSON Stacks是串行操作的,因爲如果完整的話你只能解析一個有效的JSON-String。如果你真的想要將視頻數據打包成JSON,這顯然不是JSON曾經打算過的,並且幾乎所有設置都應該有更好的解決方案),那麼最好的方法就是BASE64編碼視頻在一個流中,所以你可以將它的塊讀入內存,將它們打包成JSON字符串並將它們發送到服務器,服務器可以使用這些塊將視頻流式傳輸到文件或播放它,或者在內存中重建它...

@BSON之前被提到過 - 使用它可能是明智的,因爲JSON數據將被壓縮。但是它並沒有改變你必須以不利的格式編碼你的視頻數據的事實,這將擴大傳輸的數據,並將在雙方的性能上佔據公平的份額!


但我可以想象使用JSON進行視頻傳輸的場景可能是明智的。如果你有大量的小視頻(用戶可以選擇和整理的小視頻片段或視頻片段),那麼可靠的處理數據結構來管理這些視頻非常值得額外的傳輸成本...

0

你可以任意的二進制文件編碼爲base64,然後輸出JSON字符串是這樣的:

<?php 
$fgc = file_get_contents('yourfile.gif'); //can be any binary 
$bindata = base64_encode($fgc); 
$arr = array('name'=>'yourfile.gif','mime'=>'image/gif','data'=>$bindata); 
echo json_encode($arr); 
?> 

視頻,用你最好的MIME類型...

在安卓方面,對數據進行解碼和使用MIME類型,選擇正確的視圖等'...

1

從PHP發送的JSON的二進制數據是非常簡單的:

$data = file_get_contents($filename); 
echo json_encode(array('filecontent' => $data)); 

至少在理論上這是可行的。它在實踐中不起作用的原因是$data的大小有限(必須符合內存限制),並且JSON並不意味着要傳輸兆字節的數據。

編碼效率低下。無論您是使用本機字節,那麼您將遇到任何不可打印字符的轉義序列,使這些字節變大六倍(unicode轉義序列使用反斜槓,字母「u」和四個十六進制數字)。或者你使用base64編碼,這會將每個字節炸掉大約33%。不包括最基本的JSON包裝的開銷。

提供一個本地的字節流與一個適當的頭似乎是更好的主意。您可以直接將該數據流饋送到視頻編解碼器中進行重播,無需解析JSON,解碼base64並將所有內容重新組合成視頻數據流。

相關問題