Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: конвертация видео в mp4 #227

Merged
merged 1 commit into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
### Распознавание речи :speaking_head:
С помощью [VK Cloud Solutions](https://mcs.mail.ru). Бот может распознавать голосовые сообщения.

### Конвертация видео
Бот автоматически сконвертирует видео в mp4 из других форматов

### Команды :monocle_face:
* */statistic* - статистика сообщений юзера в чате;
* */top10* - топ 10 спамеров в чате;
Expand Down
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ dependencies {

implementation("io.github.resilience4j:resilience4j-kotlin:1.7.1")
implementation("io.github.resilience4j:resilience4j-ratelimiter:1.7.1")

implementation("ws.schild:jave-all-deps:3.4.0")
}

tasks.withType<KotlinCompile> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.github.djaler.evilbot.handlers

import com.github.djaler.evilbot.handlers.base.MessageHandler
import com.github.djaler.evilbot.service.VideoConvertService
import com.github.djaler.evilbot.utils.toTemporaryFile
import dev.inmo.tgbotapi.bot.RequestsExecutor
import dev.inmo.tgbotapi.extensions.api.files.downloadFile
import dev.inmo.tgbotapi.extensions.api.send.media.sendVideo
import dev.inmo.tgbotapi.extensions.api.send.reply
import dev.inmo.tgbotapi.extensions.api.send.withUploadVideoAction
import dev.inmo.tgbotapi.extensions.utils.asContentMessage
import dev.inmo.tgbotapi.extensions.utils.asDocumentContent
import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile
import dev.inmo.tgbotapi.types.message.abstracts.Message
import org.springframework.stereotype.Component
import java.io.File
import java.util.*
import kotlin.io.path.createTempDirectory

@Component
class VideoConverterHandler(
private val requestExecutor: RequestsExecutor,
private val videoConvertService: VideoConvertService,
) : MessageHandler() {
override suspend fun handleMessage(message: Message): Boolean {
val document = message.asContentMessage()?.content?.asDocumentContent() ?: return false
val mimeType = document.media.mimeType ?: return false
if (mimeType.primaryType != "video") {
return false
}
if (mimeType.subType == "mp4") {
return false
}

requestExecutor.withUploadVideoAction(message.chat) {
val videoBytes = requestExecutor.downloadFile(document)

val mp4File = convertToMp4(videoBytes, document.media.fileName ?: "video")

try {
requestExecutor.sendVideo(message.chat, video = mp4File.asMultipartFile())
requestExecutor.reply(message, text = "Вот тебе mp4, не благодари")
} finally {
mp4File.delete()
}
}

return true
}

private fun convertToMp4(bytes: ByteArray, fileName: String): File {
val directory = createTempDirectory(UUID.randomUUID().toString()).toFile()

bytes.toTemporaryFile(directory, fileName).use { inputFile ->
val outputFile = File(directory, inputFile.nameWithoutExtension + ".mp4")
videoConvertService.convertToMp4(inputFile, outputFile)
return outputFile
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.github.djaler.evilbot.service

import org.springframework.stereotype.Service
import ws.schild.jave.Encoder
import ws.schild.jave.MultimediaObject
import ws.schild.jave.encode.AudioAttributes
import ws.schild.jave.encode.EncodingAttributes
import ws.schild.jave.encode.VideoAttributes
import java.io.File

@Service
class VideoConvertService {
fun convertToMp4(input: File, output: File) {
val audioAttributes = AudioAttributes()
val videoAttributes = VideoAttributes()
val encodingAttributes = EncodingAttributes().apply {
setAudioAttributes(audioAttributes)
setVideoAttributes(videoAttributes)
setOutputFormat("mp4")
}

val encoder = Encoder()
encoder.encode(MultimediaObject(input), output, encodingAttributes)
}
}
13 changes: 13 additions & 0 deletions src/main/kotlin/com/github/djaler/evilbot/utils/Files.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,23 @@ import dev.inmo.tgbotapi.requests.abstracts.asMultipartFile
import io.ktor.client.statement.*
import io.ktor.utils.io.streams.*
import org.springframework.core.io.ClassPathResource
import java.io.File

fun ClassPathResource.asMultipartFile() = MultipartFile(
filename ?: throw IllegalArgumentException("Incorrect resource provided: $this"),
inputSource = { inputStream.asInput() }
)

suspend fun HttpResponse.asMultipartFile(filename: String) = bodyAsChannel().asMultipartFile(filename)

fun ByteArray.toTemporaryFile(parent: File, name: String): TempFile {
val file = TempFile(parent.resolve(name).path)
file.writeBytes(this)
return file
}

class TempFile(path: String) : File(path), AutoCloseable {
override fun close() {
delete()
}
}