在 Android 中将 mp4 保存到外部存储时视频文件损坏

问题描述 投票:0回答:0

我试图在 url 的帮助下保存修剪后的 mp4 文件。我正在使用 https://github.com/a914-gowtham/android-video-trimmer 来修剪我的视频,修剪后更新的 uri 很好,因为我尝试在

exoplayer
中播放它并且它有效,问题发生了当我尝试将其保存到外部存储时。我可以看到我的文件也被保存到外部存储中,但是当我尝试通过第三方应用程序(如 vlc、mxplayer 等)保存后播放它时,它们会抛出错误。下面是我在获取 uri 后保存视频的代码

class MainActivity : AppCompatActivity() {

    private lateinit var uri: Uri
    private lateinit var playerView: PlayerView

    private val REQUEST_CODE_PERMISSIONS = 10
    private val REQUIRED_PERMISSIONS =
        mutableListOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE).toTypedArray()

    private var player: ExoPlayer? = null
    private var playWhenReady = true
    private var currentItem = 0
    private var playbackPosition = 0L

    private fun setUpPlayer(url: String){
        player = ExoPlayer.Builder(this)
            .build()
            .also { exoPlayer ->
                playerView.player = exoPlayer
                val mediaItem = MediaItem.fromUri(url)
                exoPlayer.setMediaItem(mediaItem)
                exoPlayer.playWhenReady = playWhenReady
                exoPlayer.seekTo(currentItem, playbackPosition)
                exoPlayer.prepare()
            }
    }


    private val startForResult =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
            if (result.resultCode == Activity.RESULT_OK &&
                result.data != null
            ) {
                uri = Uri.parse(TrimVideo.getTrimmedVideoPath(result.data))
                Log.i("TAG", "Trimmed path:: $uri")
                setUpPlayer(uri.toString())
                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
                    lifecycleScope.launch {
                        val uri = saveVideoToExternalStorage()
                        Log.i("helloooo", "3487438734784387")
                        Toast.makeText(this@MainActivity, "Uri is $uri", Toast.LENGTH_LONG).show()
                    }
                } else {
                    ActivityCompat.requestPermissions(
                        this,
                        REQUIRED_PERMISSIONS,
                        REQUEST_CODE_PERMISSIONS
                    )
                }



            } else
                Log.i("TAG", "Trimmed path11111:: Errorr")
        }

    private val singleVideoPickerLauncher =
        registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { videoUri ->
            TrimVideo.activity(videoUri.toString())
                .setHideSeekBar(true)
                .start(this, startForResult)
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        playerView = findViewById(R.id.playerview)

        findViewById<Button>(R.id.btn).setOnClickListener {
            singleVideoPickerLauncher.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.VideoOnly))
        }


    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_CODE_PERMISSIONS) {
            if (allPermissionsGranted()) {
                lifecycleScope.launch {
                    Log.i("helloooo", "000000")
                    val uri = saveVideoToExternalStorage()
                    Log.i("helloooo", "1111111")
                    Toast.makeText(this@MainActivity, "Uri is $uri", Toast.LENGTH_LONG).show()
                }
            } else {
                Log.i("TAG", "Permission denied")

            }
        }
    }

    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(
            this, it
        ) == PackageManager.PERMISSION_GRANTED
    }

    private suspend fun saveVideoToExternalStorage(): Uri? {
        return withContext(Dispatchers.Default) {
            Log.i("helloooo", "1")

            val videoCollection = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
            } else {
                MediaStore.Video.Media.EXTERNAL_CONTENT_URI
            }

            val file = uri.path?.let { File(it) }

            Log.i("helloooo", "2")
            val contentValues = ContentValues().apply {
                Log.i("helloooo", "3")

                put(MediaStore.Video.Media.DATA, uri.path)
                put(MediaStore.MediaColumns.DISPLAY_NAME, "${System.currentTimeMillis()}${file?.name}.mp4")

                put(MediaStore.Video.Media.TITLE, "${System.currentTimeMillis()}${file?.name}.mp4")
                put(MediaStore.Video.Media.MIME_TYPE, "video/mp4")
                put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis() / 1000)
            }
            Log.i("helloooo", "4")
            val uri =
                contentResolver.insert(videoCollection, contentValues)
            Log.i("helloooo", "5 ${uri}")
            uri
        }
    }
}
android kotlin android-contentprovider android-external-storage
© www.soinside.com 2019 - 2024. All rights reserved.