У нас проблема с JavaFX MediaPlayer уже более месяца.Мы прочитали и попробовали все подобные проблемы здесь, ничего не получалось.Простейший пример: это информационное приложение с 2 видео из папки, воспроизводимой непрерывно в цикле.Через некоторое время (иногда 2 часа, иногда 2 дня) видео начинает замедляться, продолжительность увеличивается, время от времени останавливается, звук искажается.
ОС: win7 64b (Ultimate) SP1 Процессор Intel Celeron N3150 @ 1.6 ГГц 8ГБ Ram java 1.8 и 1.10, 64b
Пробовал: обновление ОС, последнее.Обновления драйверов, другие драйверы.JDK 64b, 1.8 последние обновления, JDK 1.10 последние.Изменение кода (добавление удаления, закрытие, установка нуля, кэширование ... каждое предложение по стеку) Изменение кодировщиков видео: MPEG-4, H.264 и H.264-HD, 1500/2000/4000/8000 кбит / с, 25 кадров в секунду Изменение разрешения: 1280x720, звук: AAC, 1 и 2 канала, 48 и 44 кГц, битрейт 128 кбит / с и другие.Пробные видео без звука.
Практически каждая возможная комбинация этих видео / звуковых кодеров, битрейта, разрешения, частоты кадров ... Мы профилировали на утечки памяти: память растет некоторое время и перестает расти.Это нормально (мы думаем).
Ничто из того, что мы пробовали, не сработало.Нет ошибок, нет исключений на MediaView, Media, Player.Системных событий нет.
Запутано: мы заметили, что при нормальной работе CPU составляет 20-30%, но когда видео начинает зависать, оно ниже, 5-15%.
Код (последняя версия):
import java.io.File
import akka.actor.{Actor, ActorLogging, Props, Timers}
import akka.pattern._
import com.commercial.activity.MMDriver.ShowNextMedia
import javafx.event.EventHandler
import javafx.scene.media.{Media, MediaErrorEvent, MediaPlayer, MediaView}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
object MMDriver {
def props(rootFolder: File, allowedExtension: List[String],
showMedia: (MMedia) => Unit): Props = Props(new MMDriver(rootFolder, allowedExtension, showMedia))
case object Start
case class MediaCreated(list: List[MMedia])
case object ShowNextMedia
}
class MMDriver(rootFolder: File, allowedExtensions: List[String],
showMedia: (MMedia) => Unit) extends Actor with ActorLogging with Timers {
object TimerKey
var started = false
var medias = List[MMedia]()
var index = 0
override def receive: Receive = {
case MMDriver.Start if (!started) =>
started = true
Future {
loadMedia(rootFolder, allowedExtensions)
.map { file =>
val media = new Media(file.toURI.toURL.toString)
val player = new MediaPlayer(media)
//next video
player.setOnEndOfMedia(new Runnable {
override def run(): Unit = {
self ! ShowNextMedia
}
})
val mediaView = new MediaView(player)
setErrorHandlers(player, media, mediaView)
MMedia(file, media, player, mediaView)
}
}
.map(media => MMDriver.MediaCreated(media.toList))
.pipeTo(self)
case MMDriver.MediaCreated(list) =>
medias = list
if (medias.nonEmpty) {
self ! ShowNextMedia
}
case MMDriver.ShowNextMedia =>
val media = medias(index)
showMedia(media)
index = index + 1
index = index % medias.size
case msg =>
log.info("not processed message {}", msg)
}
private def loadMedia(folder: File, allowedExtensions: List[String]): Array[File] = {
folder.listFiles()
.filter { file =>
allowedExtensions.exists(file.getName.endsWith(_))
}
}
private def setErrorHandlers(player: MediaPlayer, media: Media, mediaView: MediaView): Unit = {
player.setOnError(new Runnable {
override def run(): Unit = {
log.error(player.getError, "error in player")
}
})
media.setOnError(new Runnable {
override def run(): Unit = {
log.error(media.getError, "error in media")
}
})
mediaView.setOnError(new EventHandler[MediaErrorEvent] {
override def handle(event: MediaErrorEvent): Unit = {
log.error(event.getMediaError, "error in mediaView")
}
})
}
}
Любое предложение, что попробовать дальше - у нас нет идей?!