почему мое записанное видео становится 0 байт после загрузки на сервер с использованием модернизации?

#android #kotlin #retrofit2 #video-capture

#Android #kotlin #retrofit2 #захват видео

Вопрос:

мое приложение пытается захватить видео, а затем результат будет отправлен на сервер

итак, я записываю видео, используя приведенный ниже код, но когда я загружаю его на сервер, размер файла всегда равен 0 байт

потому что я создаю его во временном файле?

введите описание изображения здесь

вот код для записи видео

      private fun recordVideo() {


        val videoFile = createVideoFile()

        videoFile?.let {
            videoUri = FileProvider.getUriForFile(mContext,"com.video.record.fileprovider",it)
            val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
            intent.putExtra(MediaStore.EXTRA_OUTPUT,videoUri) 
            startActivityForResult(intent,REQUEST_VIDEO_CAPTURE)
        }

    }

    private fun createVideoFile() : File? {
        val fileName = "myVideoAndroid"
        val storageDir = mActivity.getExternalFilesDir(Environment.DIRECTORY_MOVIES)
        return File.createTempFile(fileName,".mp4",storageDir) // <---- because I make it in temporary file ?
    }
  

а вот тег поставщика в манифесте

         <provider
            android:authorities="com.video.record.fileprovider"
            android:name="androidx.core.content.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">

            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />

        </provider>
  

а вот путь к файлу xml

 <?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android = "http://schemas.android.com/apk/res/android">
    <external-path
        name="my_videos"
        path="Android/data/com.xxxx.mediauploader/files/Movies"/>

</paths>
  

видео кажется хорошим перед загрузкой на сервер, я могу воспроизвести его отлично.

а затем я загружаю его с помощью модернизации, используя приведенный ниже код

интерфейс

  @Multipart
    @POST("uploadvideo")
    fun uploadVideo(
            @Part video: MultipartBody.Part
    ): Call<UploadResponse>
  

а затем использовал его так

 private fun createVideoFile() : File? {
    val fileName = "myVideoAndroid"
    val storageDir = mActivity.getExternalFilesDir(Environment.DIRECTORY_MOVIES)
    return File.createTempFile(fileName,".mp4",storageDir)
}

val file = File(createVideoFile()!!.absolutePath)
val fileVideoPart = MultipartBody.Part.createFormData("videoFile", file.name, RequestBody.create("video/*".toMediaTypeOrNull(), file))
val call = uploadMediaAPI.uploadVideo(video = fileVideoPart)

call.enqueue(object : Callback<UploadResponse>  {


})
  

Я могу успешно загрузить его, но результат всегда равен 0 байтам на сервере

как это решить?

Комментарии:

1. Вы вызываете createVideoFile() . Который создает пустой файл (и удаляет старый), а затем вы загружаете этот пустой файл. В этом вся ошибка. Вместо этого вы должны использовать файл, который вы создали ранее для поставщика файлов. Вот и все.

Ответ №1:

Я, наконец, могу решить эту проблему, возможно, потому videoUri , что создается во временном файле, поэтому нам нужно преобразовать его в реальный файл

передайте это videoFile в свою модернизацию

 val videoFile = fileFromContentUri(mContext,videoUri) // <--- pass your temporary videoUri here
  

код для fileFromContentUri будет выглядеть так

     fun fileFromContentUri(context: Context, contentUri: Uri): File {
        // Preparing Temp file name
        val fileExtension = getFileExtension(context, contentUri)
        val fileName = "temp_file"   if (fileExtension != null) ".$fileExtension" else ""

        // Creating Temp file
        val tempFile = File(context.cacheDir, fileName)
        tempFile.createNewFile()

        try {
            val oStream = FileOutputStream(tempFile)
            val inputStream = context.contentResolver.openInputStream(contentUri)

            inputStream?.let {
                copy(inputStream, oStream)
            }

            oStream.flush()
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return tempFile
    }

    private fun getFileExtension(context: Context, uri: Uri): String? {
        val fileType: String? = context.contentResolver.getType(uri)
        return MimeTypeMap.getSingleton().getExtensionFromMimeType(fileType)
    }

    @Throws(IOException::class)
    private fun copy(source: InputStream, target: OutputStream) {
        val buf = ByteArray(8192)
        var length: Int
        while (source.read(buf).also { length = it } > 0) {
            target.write(buf, 0, length)
        }
    }
  

Комментарии:

1. finally can solve this problem, maybe because the videoUri is created in temporary file, so we need to convert it to real file Но это не было причиной. И это было не то, что вы сделали.

2. У вас был Uri, который указывал на ваш файл. И вы использовали uri для загрузки файла. Но вы использовали uri, как если бы это был путь к файлу. Но uries не являются путями к файлам. Ну, в основном нет. Итак, ничего не было загружено. После этого вы сделали копию файла и использовали путь к файлу копии для загрузки копии.

3. Все это было не нужно, так как вы могли использовать uri напрямую для загрузки файла.

4. @blackapps На самом деле я перепробовал так много способов, но это не сработало. это будет более полезно, если у вас есть лучший код. да, возможно, это не очень хороший способ решить проблему, но он работает

5. Конечно, здорово, что вы нашли решение. Но все это было не нужно. Даже не используя uri. Теперь я рассказал вам в комментарии, что пошло не так.