Загрузить видео на FTP Android - PullRequest
0 голосов
/ 02 ноября 2019

Я создал приложение, которое требует загрузки видео на сервер по FTP. Я искал много вариантов, но как только файл загружен, он не воспроизводится. Кто-нибудь может мне помочь?

1 Ответ

0 голосов
/ 02 ноября 2019

Вот части отправителя данных моего BackgroundSenderService. Я использовал библиотеку AndroidNetworking.

Мой сервис запускается в определенные периоды для проверки БД, которая имеет неотправленный медиафайл.

Для результатов успеха и ошибокЯ обновил базу данных, но вы можете отправлять Localbroadcasts для запуска некоторых элементов интерфейса в пользовательском интерфейсе.

private void checkDbForUpload() {
    ((MainApp) getApplicationContext()).setMediaSenderIsIdle(false);
    MediaModel media = ((MainApp) getApplicationContext()).getFirstUnsendMedia(mContext);
    if (media != null) {
        if (((MainApp) getApplicationContext()).getHasMission() && ((MainApp) getApplicationContext()).getLastResponse().getCaseId().equals(media.getCaseId())) {
            stopThisService();
            return;
        }
        boolean canBeginUpload = ((MainApp) getApplicationContext()).canBeginMediaUpload(mContext);
        if (canBeginUpload) {
            Log.d(TAG, "checkDbForUpload: we have connected and we have file to upload");
            startUploadingProcess(media);
        } else {
            ((MainApp) getApplicationContext()).setMediaSenderIsIdle(true);
            stopThisService();
        }
    } else {
        ((MainApp) getApplicationContext()).setMediaSenderIsIdle(true);
        stopThisService();
    }
}


private void startUploadingProcess(MediaModel media) {
    int mediaStatus = media.getUploadStatus();
    Log.d(TAG, "beginMediaUploadProcess: #" + media.getId() + " Status: " + mediaStatus);
    if (media.getRetryCount() > Constants.UPLOAD_ERROR_RETRY_COUNT) {
        media.setSessionId("");
        saveMediaToDb(media);
    }
    switch (mediaStatus) {
        case Constants.MEDIA_STATUS_UPLOADED:
            deleteMediaFromDbAndDisk(media);
            checkDbForUpload();
            break;
        case Constants.MEDIA_STATUS_UPLOADING:
        case Constants.MEDIA_STATUS_WAITING:
        case Constants.MEDIA_STATUS_ERROR:
            if (media.getSessionId() != null && !media.getSessionId().equals("")) {
                Log.d(TAG, "startUploadingProcess: has session");
                startPutWithoutBody(media);
            } else {
                Log.d(TAG, "startUploadingProcess: no session");
                getMediaEndpoint(media);
            }
            break;
    }
}

private void startPostTask(MediaModel media) {
    media.setSessionId("");
    setMediaAsWaiting(media);
    File file = new File(media.getFile());
    String contentType = getMimeType(file.getPath());

    setMediaAsUploading(media);
    String postUrl = ENDPOINT + "?uploadType=resumable&name=" + createSendingFileName(media);
    AndroidNetworking.post(postUrl)
            .setTag("uploadRequest")
            .setPriority(Priority.HIGH)
            .addHeaders("X-Api-Key", Constants.API_KEY_UPLOAD)
            .addHeaders("Content-Type", "application/json")
            .addHeaders("X-Upload-Content-Type", contentType)
            .addHeaders("X-Upload-Content-Length", String.valueOf(file.length()))
            .addJSONObjectBody(prepareMetaData(media).toJSON())
            .build()
            .getAsJSONObject(new JSONObjectRequestListener() {
                @Override
                public void onResponse(JSONObject response) {
                    Log.d(TAG, "onResponse: " + response.toString());
                    UploadPostResponseModel responseModel = new UploadPostResponseModel(response);
                    if (responseModel.getStatusCode() == Constants.HTTP_STATUS_OK) {
                        media.setSessionId(responseModel.getId());
                        try {
                            startPutTask(media);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } else {
                        setMediaUploadError(media);
                    }
                }

                @Override
                public void onError(ANError anError) {
                    Log.d(TAG, "onError: " + anError.getErrorDetail());
                    setMediaUploadError(media);
                }
            });
}

private void startPutWithoutBody(MediaModel media) {
    String putUrl = ENDPOINT + (ENDPOINT.contains("?") ? "&" : "?") + "upload_id=" + media.getSessionId();
    AndroidNetworking.put(putUrl)
            .setTag("putRequest")
            .setPriority(Priority.HIGH)
            .addHeaders("X-Api-Key", Constants.API_KEY_UPLOAD)
            .addHeaders("Content-Range", getContentRangeString(media))
            .build()
            .getAsJSONObject(new JSONObjectRequestListener() {
                @Override
                public void onResponse(JSONObject response) {
                    Log.d(TAG, "onResponse: " + response.toString());
                    //UploadPostResponseModel responseModel = new UploadPostResponseModel(response);
                }

                @Override
                public void onError(ANError anError) {
                    setMediaUploadError(media);
                }
            });
}

private void startPutTask(MediaModel media) {
    if (!((MainApp) getApplicationContext()).canBeginMediaUpload(mContext)) {
        setMediaAsWaiting(media);
        stopThisService();
    }
    //if fails -> consider using this https://stackoverflow.com/a/54961878/1492681
    try {
        File tmpDir = mContext.getCacheDir();
        File tmpFile = File.createTempFile("TMPFILE", media.getSessionId(), tmpDir);
        File orgFile = new File(media.getFile());
        int startIndex = (int) media.getUploadedBytes();
        Log.d(TAG, "startIndex: " + startIndex);
        int bytesLeft = (int) (orgFile.length() - startIndex);
        Log.d(TAG, "bytesLeft: " + bytesLeft);

        RandomAccessFile f = new RandomAccessFile(media.getFile(), "r");

        int len = Constants.CHUNKSIZE;

        if (Constants.CHUNKSIZE >= bytesLeft) {
            len = bytesLeft;
        }
        Log.d(TAG, "len: " + len);
        byte[] buffer = new byte[len];
        f.seek(startIndex);
        f.read(buffer, 0, len);
        Log.d(TAG, "buffer: " + buffer.length);
        int endIndex = startIndex + len;
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tmpFile));
        bos.write(buffer);
        bos.flush();
        bos.close();

        //send chunk here
        String putUrl = ENDPOINT + "?uploadType=resumable&upload_id=" + media.getSessionId();
        AndroidNetworking.put(putUrl)
                .setTag("putRequest")
                .setPriority(Priority.HIGH)
                .addHeaders("X-Api-Key", Constants.API_KEY_UPLOAD)
                .addHeaders("Content-Range", getContentRangeString(media))
                .addFileBody(tmpFile)
                .build()
                .getAsOkHttpResponse(new OkHttpResponseListener() {
                    @Override
                    public void onResponse(Response response) {
                        switch (response.code()) {
                            case Constants.HTTP_STATUS_CREATED:
                            case Constants.HTTP_STATUS_OK:
                                setMediaAsUploaded(media);
                                break;
                            case Constants.HTTP_STATUS_PERMANENT_REDIRECT:
                            case Constants.HTTP_STATUS_RANGENOTSATISFIABLE:
                                Log.d(TAG, "onResponse: " + response.toString());
                                long receivedBytes = parseRange(response);
                                Log.d(TAG, "uploaded: " + receivedBytes + " of " + orgFile.length());
                                media.setUploadedBytes(receivedBytes);
                                setMediaAsUploading(media);
                                Log.d(TAG, "onResponse: receivedBytesFromServer: " + receivedBytes);
                                try {
                                    startPutTask(media);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                                break;
                            default:
                                setMediaUploadError(media);
                                break;
                        }

                    }

                    @Override
                    public void onError(ANError anError) {
                        setMediaUploadError(media);
                    }
                });

    } catch (IOException | ArrayIndexOutOfBoundsException e) {
        e.printStackTrace();
        setMediaUploadError(media);
    }
}

private String getContentRangeString(MediaModel media) {
    File file = new File(media.getFile());
    long fileLength = file.length();
    String contentRange = "bytes */" + fileLength;
    Log.d(TAG, "getContentRangeString: " + contentRange);
    return contentRange;
}
...