我试图在 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
}
}
}