我的环境是我要安装vlc的Alpine容器
FROM fabric8/java-alpine-openjdk8-jre
RUN apk update && \
apk upgrade && \
apk add vlc vlc-xorg vlc-daemon
通过这个容器,我可以使用vlc命令行转换文件。 (发生一些错误,但文件已转换)
vlc -I dummy 1234.mp4 --no-sout-video --sout "#transcode{acodec=mp3, ab=96, channels=2,samplerate=44100}:standard{mux=mp4,dst=1234.mp3,access=file}" vlc://quit
[000055f958d31180] dbus interface error: Failed to connect to the D-Bus session daemon: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
[000055f958d31180] main interface error: no suitable interface module
[00007f753b5bcb60] main libvlc error: interface "dbus,none" initialization failed
[000055f958d35640] main interface error: no suitable interface module
[00007f753b5bcb60] main libvlc error: interface "globalhotkeys,none" initialization failed
[000055f958d35640] dummy interface: using the dummy interface module...
[000055f958f54140] idummy demux: command `quit'
ls -ltrah 1234.mp3
-rw-r--r-- 1 1001 root 4.9M Dec 11 23:27 1234.mp3
然后我尝试在同一容器上对vlcj进行相同操作,但mediaApi.play引发致命错误
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x0000000000003f36, pid=7, tid=0x00007fb727b71b20
#
# JRE version: OpenJDK Runtime Environment (8.0_222-b10) (build 1.8.0_222-b10)
# Java VM: OpenJDK 64-Bit Server VM (25.222-b10 mixed mode linux-amd64 compressed oops)
# Derivative: IcedTea 3.13.0
# Distribution: Custom build (Wed Oct 2 14:20:25 UTC 2019)
# Problematic frame:
# C 0x0000000000003f36
[[EDIT]异步转换(等待或取消睡眠)
案例:MediaPlayer.media()。play
mediaApi.prepare和mediaApi.isValid均返回true。
@Singleton
class ConverterMPService() {
val VLC_GLOBAL_OPTIONS = arrayListOf<String>(
"--file-logging",
"--logfile=tim.log",
"--log-verbose=3",
":no-sout-video",
":intf", "dummy"
)
private val LOG = Logger.getLogger(ConverterMPService::class.java)
var factory = MediaPlayerFactory(VLC_GLOBAL_OPTIONS)
var mediaPlayer = factory.mediaPlayers().newMediaPlayer()
fun onStart(@Observes ev: StartupEvent?) {
LOG.info("The vlc converterMP is starting...")
}
fun onStop(@Observes ev: ShutdownEvent?) {
LOG.info("The vlc converterMP is stopping...")
release()
}
fun convert(source: File, target: File) {
if (target.exists()) target.delete()
val options = arrayOf<String>(
":no-sout-video",
":sout=#transcode{acodec=mp3,ab=96,channels=2}:standard{mux=mp4,dst=${target.path},access=file}",
":intf", "dummy"
)
if (source.exists()) {
val mediaApi = mediaPlayer.media()
mediaPlayer.events().addMediaPlayerEventListener(LoggingMediaPlayerEventAdapter() as MediaPlayerEventListener)
mediaPlayer.events().addMediaPlayerEventListener(object : MediaPlayerEventAdapter() {
override fun finished(mp: MediaPlayer?) {
LOG.info("Finished MepiaPlayer")
//blobStorageService.upload(target)
}
})
var bPrepare = mediaApi.prepare(source.path, *options)
LOG.info("Mediaplayer prepare ${source.name}:$bPrepare")
var bIsvalid = mediaApi.isValid
LOG.debug("Mediaplayer validation check of ${source.name} is $bIsvalid")
var bPlay = mediaApi.play(source.path, *options)
LOG.debug("Mediaplayer playing ${source.name} is $bPlay")
}
}
fun release() {
LOG.info("Releasing mediaPlayer")
mediaPlayer.release()
LOG.info("Releasing factory")
factory.release()
}
}
但是发生JVM崩溃
2019-12-13 23:02:18,262 INFO [com.lg.vlc.ConverterMPService] (main) The vlc converterMP is starting...
2019-12-13 23:02:18,281 INFO [com.lg.vlc.ConverterService] (main) The vlc converter is starting...
2019-12-13 23:02:18,281 INFO [io.quarkus] (main) speech-microsoft-service 1.0-SNAPSHOT (running on Quarkus 1.0.1.Final) started in 3.125s. Listening on: http://0.0.0.0:8080
2019-12-13 23:02:18,286 INFO [io.quarkus] (main) Profile prod activated.
2019-12-13 23:02:18,286 INFO [io.quarkus] (main) Installed features: [cdi, kotlin, resteasy, resteasy-jackson]
2019-12-13 23:02:34,081 INFO [com.lg.spe.api.LoggingFilter] (vert.x-worker-thread-0) Request POST /speech2text/audio/addmp/1234mp from IP 172.17.0.1:46948
2019-12-13 23:02:36,051 TRACE [com.lg.vlc.LoggingMediaPlayerEventAdapter] (vert.x-worker-thread-0) mediaChanged(mediaPlayer=uk.co.caprica.vlcj.player.base.MediaPlayer@fb6ecb,media=uk.co.caprica.vlcj.media.MediaRef@2f89dc8f)
2019-12-13 23:02:36,059 TRACE [com.lg.vlc.LoggingMediaPlayerEventAdapter] (vert.x-worker-thread-0) volumeChanged(mediaPlayer=uk.co.caprica.vlcj.player.base.MediaPlayer@fb6ecb,volume=-1.0)
2019-12-13 23:02:36,066 INFO [com.lg.vlc.ConverterMPService] (vert.x-worker-thread-0) Mediaplayer prepare 1234mp.mp4:true
2019-12-13 23:02:36,066 DEBUG [com.lg.vlc.ConverterMPService] (vert.x-worker-thread-0) Mediaplayer validation check of 1234mp.mp4 is true
2019-12-13 23:02:36,070 TRACE [com.lg.vlc.LoggingMediaPlayerEventAdapter] (vert.x-worker-thread-0) mediaChanged(mediaPlayer=uk.co.caprica.vlcj.player.base.MediaPlayer@fb6ecb,media=uk.co.caprica.vlcj.media.MediaRef@6df18742)
2019-12-13 23:02:36,074 DEBUG [com.lg.vlc.ConverterMPService] (vert.x-worker-thread-0) Mediaplayer playing 1234mp.mp4 is true
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x0000000000003f36, pid=275, tid=0x00007f650d03db20
并且dist文件的大小为0
ls -ltrah 1234*
-rw-r--r-- 1 1001 root 75.9M Dec 13 22:32 1234mp.mp4
-rw-r--r-- 1 1001 root 0 Dec 13 22:32 1234mp.mp4.mp3
Case mediaListPlayer.controls()。play()
@Singleton
class ConverterService() {
val LOG = Logger.getLogger(ConverterService::class.java)
val VLC_GLOBAL_OPTIONS = arrayListOf<String>(
"--file-logging",
"--logfile=tim.log",
"--log-verbose=3",
":no-sout-video",
":intf=dummy"
)
var mediaFactory = MediaPlayerFactory(VLC_GLOBAL_OPTIONS)
var mediaListPlayer = mediaFactory.mediaPlayers().newMediaListPlayer()
var mediaPlayer: EmbeddedMediaPlayer = mediaFactory.mediaPlayers().newEmbeddedMediaPlayer()
fun onStart(@Observes ev: StartupEvent?) {
LOG.info("The vlc converter is starting...")
mediaListPlayer.mediaPlayer().setMediaPlayer(mediaPlayer)
}
fun onStop(@Observes ev: ShutdownEvent?) {
LOG.info("The vlc converter is stopping...")
release()
}
private fun release() {
LOG.info("Releasing mediaListPlayer")
mediaListPlayer.release()
LOG.info("Releasing factory")
mediaFactory.release()
}
fun convert(source: File, target: File) {
if (target.exists()) target.delete()
if (source.exists()) {
val options = arrayOf<String>(
":no-sout-video",
":sout=#transcode{acodec=mp3,ab=96,channels=2}:standard{mux=mp4,dst=${target.path},access=file}",
":intf=dummy"
)
var mediaList = mediaFactory.media().newMediaList()
mediaList.media().add(source.path, *options)
val mediaListRef = mediaList.newMediaListRef()
try {
mediaListPlayer.list().setMediaList(mediaListRef)
} finally {
mediaListRef.release()
}
mediaListPlayer.events().addMediaListPlayerEventListener(LoggingMediaListPlayerEventAdapter())
mediaListPlayer.events().addMediaListPlayerEventListener(object : MediaListPlayerEventAdapter() {
override fun mediaListPlayerFinished(mlp: MediaListPlayer?) {
if (null != mlp) {
for (mrl in mlp.list().media().mrls()) {
var f = File("$mrl.mp3")
LOG.info("Output ${f.path} size is ${f.length()}")
// blobStorageService.upload(target)
}
}
LOG.info("mediaListPlayerFinished")
}
})
if (null != mediaListPlayer.mediaPlayer().mediaPlayer()) {
mediaListPlayer.mediaPlayer().mediaPlayer().events().addMediaPlayerEventListener(LoggingMediaPlayerEventAdapter())
} else LOG.info("mediaListPlayer.mediaPlayer().mediaPlayer() is null")
mediaListPlayer.controls().play()
}
}
}
发生JVM崩溃
2019-12-13 22:53:07,964 INFO [com.lg.vlc.ConverterMPService] (main) The vlc converterMP is starting...
2019-12-13 22:53:07,984 INFO [com.lg.vlc.ConverterService] (main) The vlc converter is starting...
2019-12-13 22:53:07,984 INFO [io.quarkus] (main) speech-microsoft-service 1.0-SNAPSHOT (running on Quarkus 1.0.1.Final) started in 2.504s. Listening on: http://0.0.0.0:8080
2019-12-13 22:53:07,988 INFO [io.quarkus] (main) Profile prod activated.
2019-12-13 22:53:07,989 INFO [io.quarkus] (main) Installed features: [cdi, kotlin, resteasy, resteasy-jackson]
2019-12-13 22:53:17,456 INFO [com.lg.spe.api.LoggingFilter] (vert.x-worker-thread-0) Request POST /speech2text/audio/add/1234 from IP 172.17.0.1:46940
2019-12-13 22:53:19,397 INFO [com.lg.vlc.ConverterService] (vert.x-worker-thread-0) mediaListPlayer.mediaPlayer().mediaPlayer() is null
2019-12-13 22:53:19,459 INFO [com.lg.vlc.LoggingMediaListPlayerEventAdapter] (vert.x-worker-thread-0) MediaListPlayer nextItem
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x0000000000003f36, pid=136, tid=0x00007f0bd628fb20
但是在这种情况下dist文件就可以了。崩溃发生在转换之后和完成的触发器之前
ls -ltrah 1234*
-rw-r--r-- 1 1001 root 75.9M Dec 13 22:53 1234.mp4
-rw-r--r-- 1 1001 root 4.9M Dec 13 22:53 1234.mp4.mp3
我尝试了不同的Linux映像,debian,ubuntu ...我不知道这与错误的vlc安装有关。
override fun finished(p0: MediaPlayer?) {
p0!!.release() // <------
isFinished = true
}
您正在尝试在处理事件时释放媒体播放器。释放媒体播放器会进行很多清理,包括释放本机资源。这几乎肯定是导致崩溃的原因。相反,请在释放出厂之前释放媒体播放器。
或者,您正在循环使用非线程安全的isFinished变量来检查视频是否已完成。
您在事件侦听器中将isFinished设置为true,然后在媒体播放器(和关联的本机媒体播放器)完成处理事件之前,另一个线程中的while循环(取决于计时)可能会继续进行到factory.release()。
您可能需要更复杂的同步机制。
您基本上是在尝试使用异步API强制进行同步处理。
vlcj“ waiter”软件包中有一些旨在解决此类问题的类。