简体   繁体   English

在参数为file的android中使用翻新功能上传视频

[英]uploading a video using retrofit in android where parameter is file

I have been following various tutorials and trying to upload video to my server using retrofit in android. 我一直在遵循各种教程,并尝试使用android中的改造将视频上传到我的服务器。 The only parameters I need is as shown in figure below 我唯一需要的参数如下图所示 在此处输入图片说明

I keep on get the timeout exception even though I have increased the timeout. 即使增加了超时时间,我仍然会收到超时异常。 This is my upload video code. 这是我的上传视频代码。

final OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .readTimeout(60, TimeUnit.SECONDS)
            .connectTimeout(60, TimeUnit.SECONDS)
            .build();
    Log.v("test_get", "get the file");
    //MultipartBody.Part vFile = MultipartBody.Part.createFormData("video", videoFile.getName(), videoBody);
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://xxxx:xxx/")
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build();

    SmileVideoAPI service = retrofit.create(SmileVideoAPI.class);
    MediaType MEDIA_TYPE = MediaType.parse("video/mp4");
    File videoFile = new File(pathToVideoFile);
    RequestBody videoBody = RequestBody.create(MEDIA_TYPE, videoFile);
    Log.v("test_get", "before uploading");
    Call<ResponseBody> call = service.uploadVideo("desc", videoBody);
    Log.v("test_get", "after uploading");
    call.enqueue(new Callback<ResponseBody>(){
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            if (response.isSuccessful())
            {
                Log.i("mok","S");
                ResponseBody rb = response.body();
                Log.i("mok",rb.toString());
            }
            else {
                Log.i("mok", "F");
                ResponseBody rb = response.errorBody();
            }
        }
        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            t.printStackTrace();
            Log.i("mok",t.getCause()+"");
            Log.i("mok","T");
            finish();
        } 
    });
    return msg;

    I have been trying taking reference from this post : 

upload video using Retrofit 2 使用翻新2上传视频

If you wish to upload files (any type) here is a PHP approach for Android that works well. 如果您想上传文件(任何类型),这里是一种适用于Android的PHP方法,效果很好。

You need a script on the server to receive files: 您需要服务器上的脚本来接收文件:

uploadfile.php uploadfile.php

<?php
$fname = $_POST['filename'];
$target_path = "/yourserverpath/".$fname;
$upload_path = $_FILES['uploadedfile']['tmp_name'];
If (move_uploaded_file($upload_path, $target_path)) {
    echo "Moved";
} else {
    echo "Not Moved";
}
?>

You can test out your uploadfile.php script on the server with the following HTML tester file on the server from a browser: 您可以通过浏览器在服务器上使用以下HTML测试器文件在服务器上测试您的uploadfile.php脚本:

Uploadfile.html: Uploadfile.html:

<form enctype="multipart/form-data" action="uploader.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="100000" />
Choose a file to upload: 
<input name="uploadedfile" type="file" /><br />
Filename on server:
<input name="filename" type="text" /><br />
<br />
<input type="submit" value="Upload File" />
</form>

Once you get the server side working to upload files from the browser, then the Android part is pretty straightforward: 一旦服务器端开始从浏览器上传文件,那么Android部分就非常简单了:

Uploader handles the uploading of files. Uploader处理文件的上传。 This class calls the uploadfile.php script on the server. 此类在服务器上调用uploadfile.php脚本。

Uploading files can be tricky, but we have a secret weapon that makes it much easier. 上载文件可能很棘手,但是我们拥有一个秘密武器,可以使上传变得更加容易。 We are going to use the DefaultHttpClient, which gives us access to MultipartEntity method. 我们将使用DefaultHttpClient,它使我们能够访问MultipartEntity方法。 This method is not available when using HttpUrlConnection. 使用HttpUrlConnection时,此方法不可用。 The fileUpload class is placed in the AsyncTask. fileUpload类位于AsyncTask中。 The selectedPicName in my example is simply your filename. 在我的示例中,selectedPicName只是您的文件名。 The postURL is the full URL of the script mentioned earlier. postURL是前面提到的脚本的完整URL。

private class fileUpload extends AsyncTask<Void, String, Void> {
    protected Void doInBackground(Void... unused) {
        // upload new picture to the server        
        String postURL = uploadFilesScript;
        File file = new File(path2, selectedPicName);
        // upload the new picture
        Uploader(postURL, file, selectedPicName);
    } 
}

The Uploader class is as follows: (Important to note that "uploadedfile" name has to match the variable in the PHP script the receives uploads.) Uploader类如下:(需要注意的是,“ uploadedfile”名称必须与接收上载的PHP脚本中的变量匹配。)

public static void Uploader(String postURL, File file, String fname) {
    try {
        DefaultHttpClient httpclient = new DefaultHttpClient();
        httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, 
                                            HttpVersion.HTTP_1_1);
        HttpPost httppost = new HttpPost(postURL);
        // the boundary key below is arbitrary,
        // it just needs to match the MPE so it can decode multipart correctly
        httppost.setHeader("Content-Type", "multipart/form-data; boundary=--32530126183148");
        MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,
                                                       "--32530126183148", 
                                                       Charset.forName("UTF-8"));
            mpEntity.addPart("uploadedfile", new FileBody((file), "application/txt"));
            mpEntity.addPart("MAX_FILE_SIZE", new StringBody("100000"));
            mpEntity.addPart("filename", new StringBody(fname));
        }
        httppost.setEntity(mpEntity);
        HttpResponse response;
        response = httpclient.execute(httppost);
        HttpEntity resEntity = response.getEntity();
          if (resEntity != null) {
                resEntity.consumeContent();
                Log.v("UPLOAD", "resEntity=" + resEntity.toString());
            }
        httpclient.getConnectionManager().shutdown();
    } catch (Throwable e) {
    }
}

MultipartEntity allows us to simply specify the file name and the file contents using the addPart method. MultipartEntity允许我们使用addPart方法简单地指定文件名和文件内容。 In the example below, the variable names match with those expected by the receiving PHP script on the server. 在下面的示例中,变量名与服务器上接收PHP脚本所期望的变量名匹配。

If we had to accomplish this uploading functionality using the HttpUrlConnection class, it would be complicated, as we would have to create our own file handling wrapper. 如果必须使用HttpUrlConnection类完成此上载功能,则将很复杂,因为我们必须创建自己的文件处理包装器。 MultipartEntity also allows us to specify character set and maximum file size. MultipartEntity还允许我们指定字符集和最大文件大小。 A unique, but arbitrary, boundary string needs to be provided which must match the server script. 需要提供一个唯一但任意的边界字符串,该字符串必须与服务器脚本匹配。

I have been using this approach in my production apps and it works really well. 我在生产应用程序中一直使用这种方法,并且效果很好。

Full disclosure- I wrote a book called Android Software Developement: A Collection of Practical Projects and uploading is covered in a Server Spinner App in Chapter 5, but this should be all you need to upload videos. 全面披露-我在第5章的服务器微调器应用程序中写了一本书,名为《 Android软件开发:实用项目和上载的集合》 ,但这只是上传视频所需的全部。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM