gpt4 book ai didi

java - 无法使用 Retrofit 上传视频,可以解决吗?

转载 作者:行者123 更新时间:2023-12-02 03:09:46 26 4
gpt4 key购买 nike

我正在尝试使用 Retrofit 作为多部分表单数据将视频上传到服务器,并且我使用 Retrofit 版本:2.02

compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'

这是 API 客户端类的代码:

ApiClient.java

    public class ApiClient {

public static final String BASE_URL = "https://api.sproutvideo.com";
private static Retrofit retrofit = null;


public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}

这是API接口(interface)的代码:

ApiInterface.java

    public interface ApiInterface {
@Multipart
@POST("/v1/videos")
Call<SproutReply> pushVideo (@Header("SproutVideo-Api-Key") String key, @Part("file\"; filename=\"pp.mp4") RequestBody file);
}

我的要求是上传使用Intent.ACTION_PICK挑选的视频。

这就是我调用 API 的方式:

 private void makeRequest(Uri uri)
{


try {
String path = uri.toString();
Log.e("PATH", path);
URI ss = new URI(uri.toString());
file = new File(ss);

}
catch (Exception e){}


RequestBody video = RequestBody.create(MediaType.parse("video/mp4"),file);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

ApiInterface apiService =
ApiClient.getClient().create(ApiInterface.class);

Call<SproutReply> call = apiService.pushVideo(KEY,video);
call.enqueue(new Callback<SproutReply>()
{
@Override
public void onResponse(Call<SproutReply> call, Response<SproutReply> response)
{
try
{
Log.e("TAG",""+response.body().toString());




}
catch (Exception e)
{
Toast.makeText(getActivity(), "Check data connection", Toast.LENGTH_SHORT).show();
}
}

@Override
public void onFailure(Call<SproutReply> call, Throwable t)
{
// Log error here since request failed
Log.e("FAILURE", t.toString());
}
});


}

此行调用会导致 NullPointerExceptioncontent == null:

RequestBody video = RequestBody.create(MediaType.parse("video/mp4"),file);

但是,在这一行中,当我将 Uri( Log.e("PATH", path); ) 记录为 String 时,我获得的值为:

content://com.android.providers.media.documents/document/video%3A75406

使用这个 Uri,我也可以在 VideoView 中播放视频,但是在 Retrofit 中它似乎崩溃了,可能是什么原因导致的以及如何修复?

这也是 logcat:

java.lang.NullPointerException: content == null
at okhttp3.RequestBody.create(RequestBody.java:103)
at com.example.demovid.UploadFragment.makeRequest(UploadFragment.java:91)
at com.example.demovid.UploadFragment.onEvent(UploadFragment.java:133)
at java.lang.reflect.Method.invoke(Native Method)
at org.greenrobot.eventbus.EventBus.invokeSubscriber(EventBus.java:485)
at org.greenrobot.eventbus.EventBus.postToSubscription(EventBus.java:416)
at org.greenrobot.eventbus.EventBus.postSingleEventForEventType(EventBus.java:397)
at org.greenrobot.eventbus.EventBus.postSingleEvent(EventBus.java:370)
at org.greenrobot.eventbus.EventBus.post(EventBus.java:251)
at com.example.demovid.MainActivity.onActivityResult(MainActivity.java:67)
at android.app.Activity.dispatchActivityResult(Activity.java:6456)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3729)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3776)
at android.app.ActivityThread.-wrap16(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1412)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5461)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

最佳答案

问题是您有一个内容 URI 而不是文件路径。当您将其传递给 File 构造函数时,它会抛出一个 FileNotFoundException,您可以使用

默默地忽略它
`catch (Exception e){}`

您可以使用 -- 来获取数据的文件描述符,而不是使用文件 -

ParcelFileDescriptor fd = getActivity().getContentResolver().openFileDescriptor(uri, "r");

并使用它来构造您的RequestBody。没有现成的方法可以从描述符创建一个描述符,但是编写一个例程来执行此操作相当容易 -

public static RequestBody createBody(final MediaType contentType, final ParcelFileDescriptor fd) {
if (fd == null) throw new NullPointerException("content == null");

return new RequestBody() {
@Override public MediaType contentType() {
return contentType;
}

@Override public long contentLength() {
return fd.getStatSize();
}

@Override public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(new ParcelFileDescriptor.AutoCloseInputStream(fd));
sink.writeAll(source);
} finally {
Util.closeQuietly(source);
}
}
};
}

然后像--

一样使用它
RequestBody video = RequestBody.createBody(MediaType.parse("video/mp4"), fd);

我还注意到您正在对媒体类型进行硬编码,您也可以通过调用 getType 从内容解析器获取类型。

关于java - 无法使用 Retrofit 上传视频,可以解决吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41236736/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com