vlcj 4.2.0 MediaPlayer.media()。play()或mediaListPlayer.controls()。play()在Linux docker容器中引发致命错误

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

我的环境是我要安装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安装有关。

libvlc vlcj
1个回答
0
投票
您的事件监听器对我来说似乎很不对劲:

override fun finished(p0: MediaPlayer?) { p0!!.release() // <------ isFinished = true }

您正在尝试在处理事件时释放媒体播放器。释放媒体播放器会进行很多清理,包括释放本机资源。这几乎肯定是导致崩溃的原因。

相反,请在释放出厂之前释放媒体播放器。

或者,您正在循环使用非线程安全的isFinished变量来检查视频是否已完成。

您在事件侦听器中将isFinished设置为true,然后在媒体播放器(和关联的本机媒体播放器)完成处理事件之前,另一个线程中的while循环(取决于计时)可能会继续进行到factory.release()。

您可能需要更复杂的同步机制。

您基本上是在尝试使用异步API强制进行同步处理。

vlcj“ waiter”软件包中有一些旨在解决此类问题的类。

© www.soinside.com 2019 - 2024. All rights reserved.