0

我已经根据 VLCj 测试文件编写了下面的简单程序。我想观看视频并将其与音频一起保存到文件中。我现在已经设法使用这些选项,以便文件保存有良好的视频。但是,帧中的图像不会移动,并且保存的视频没有音频。

import com.sun.jna.NativeLibrary;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import uk.co.caprica.vlcj.binding.internal.libvlc_state_t;
import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.discovery.NativeDiscovery;

import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.player.embedded.videosurface.CanvasVideoSurface;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
import uk.co.caprica.vlcj.runtime.x.LibXUtil;
import uk.co.caprica.vlcj.version.LibVlcVersion;
import uk.co.caprica.vlcj.binding.LibVlc;

public class Capture {

    private final JFrame frame;
    private final JPanel contentPane;
    private final Canvas canvas;
    private static MediaPlayerFactory factory;
    private static  EmbeddedMediaPlayer mediaPlayer;
    private static  CanvasVideoSurface videoSurface;
    private static String libvlcDir;
    private static boolean discovered;
    private static Capture capture;
    
    public static void main(final String[] args) {
        
       libvlcDir = "/Applications/VLC.app/Contents/MacOS/lib";
       NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), libvlcDir);

       LibXUtil.initialise();
       
       capture = new Capture();            
        
       SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                capture.start("qtcapture://0x1a11000005ac8509");
            }
        });
    }

    public Capture() {
        canvas = new Canvas();
        canvas.setBackground(Color.black);

        contentPane = new JPanel();
        contentPane.setBackground(Color.black);
        contentPane.setLayout(new BorderLayout());
        contentPane.add(canvas, BorderLayout.CENTER);

        frame = new JFrame("Capture");
        frame.setContentPane(contentPane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(50, 50);
        frame.setSize(800, 600);
        
        factory = new MediaPlayerFactory();
        mediaPlayer = factory.newEmbeddedMediaPlayer();
        videoSurface = factory.newVideoSurface(canvas);

        mediaPlayer.setVideoSurface(videoSurface);
    }

    private void start(String mrl) {
        frame.setVisible(true);

        // GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(frame);

        File dir = new File(System.getProperty("user.home"), "Videos");
        dir.mkdirs();

        DateFormat df = new SimpleDateFormat("yyyyMMdd-HHmmss");
        String fileName = dir.getAbsolutePath() + "/Capture-" + df.format(new Date()) + ".TS";
        System.out.println(fileName);
        // Tweak the options depending on your encoding requirements and audio
        // capture device (ALSA is not likely to work on Windows of course)
        
        //String[] options = {":sout=#transcode{vcodec=mp4v,vb=4096,scale=1,acodec=mpga,ab=128,channels=2,samplerate=44100}:duplicate{dst=file{dst=" + fileName + "},dst=display}", ":input-slave=alsa://hw:0,0"}; /original options - does not work on mac    
        String options = ":sout=#transcode{vcodec=h264,vb=1024,scale=1,width=360,height=300,acodec=mp4a, aenc=fdkaac,ab=256,channels=6,samplerate=44100}:duplicate{dst=file{dst=" + fileName + "},dst=display}";
        
        mediaPlayer.playMedia(mrl, options); //Records but no audio - also doesn't play in window (still image)
        
        //mediaPlayer.playMedia(mrl); //Just plays in window (no recording)
    }
    
    
    public static boolean setupVLC(){
    //Open and read VLC directory from settings file
        String msg = "";
        discovered=false;
        //If file doesn't exist, then guess
        File temp = new File(libvlcDir); 
        String os = System.getProperty("sun.arch.data.model");
        if(!temp.exists()){
            discovered = setupLibVLC();
            if (discovered){
                //update settings if found
                String tempDir = NativeLibrary.getInstance(RuntimeUtil.getLibVlcLibraryName()).toString();     
                tempDir = tempDir.substring(tempDir.indexOf("<")+1,tempDir.lastIndexOf("/"));
                libvlcDir = tempDir;
                System.out.println("VLCdir = " + libvlcDir);
            }             
        }else{
            discovered=true;
        }
        //If still can't find it, ask for pointer to it
        temp = new File(libvlcDir);
        if(temp.exists() || temp.isDirectory() || discovered){
            NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), libvlcDir);
        }else{
            msg = "Can't find correct libraries in "+libvlcDir+" Please select the file.";
            findDllFolder(msg);
            //If still not found then ask for directory  
            NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), libvlcDir);
            try{
                System.out.println("libvlc version = " + LibVlcVersion.getVersion().toString());
                discovered=true;
            }catch(java.lang.UnsatisfiedLinkError err){
                msg= "You may be using the wrong version of VLC. Can't find correct libraries in "+
                                libvlcDir+
                                " Please select the file.";
                findDllFolder(msg);
            }catch(java.lang.NoClassDefFoundError err){
                msg  = "Can't find correct libraries in "+libvlcDir+" Please select the file.";
                findDllFolder(msg);          
            }
        }
        //Final throw of the dice to test the work above
        try{
            System.out.println("libvlc version = " + LibVlcVersion.getVersion().toString());
            discovered=true;
        }catch(java.lang.UnsatisfiedLinkError err){
             discovered = false;
        }catch(java.lang.NoClassDefFoundError err){
            discovered = false;
        }
        return discovered;
    }
       public static void findDllFolder(String msg){
        JOptionPane.showMessageDialog(null, msg, "Error", JOptionPane.ERROR_MESSAGE);
                JFileChooser fileChooser = new JFileChooser();
                int result = fileChooser.showOpenDialog( null );
                if ( result == JFileChooser.APPROVE_OPTION ){  
                    libvlcDir = fileChooser.getSelectedFile().toString();
                    if(System.getProperty("os.name").contains("Mac")){
                        libvlcDir = libvlcDir + "/Contents/MacOS/lib/";
                    }else{
                        libvlcDir = libvlcDir.substring(0,libvlcDir.lastIndexOf("\\"));
                        libvlcDir = libvlcDir.replace("\\", "\\\\");
                    }
                    System.out.println("VLCdir = "+ libvlcDir);

                }
    }
    private static boolean setupLibVLC() {

        discovered = new NativeDiscovery().discover();
        
        // discovery()'s method return value is WRONG on Linux
        try {
            LibVlcVersion.getVersion();
        } catch (Exception e) {
            System.out.println("error in setupLibVLC");
        }
        return discovered;
    }
}

我在运行时收到的错误消息是:

x264 [信息]:使用 cpu 功能:MMX2 SSE2Fast SSSE3 FastShuffle SSE4.2 AVX

x264 [信息]:配置文件高,2.1 级

x264 [信息]:最终速率因子:19.03

x264 [信息]:使用 SAR=10/9

x264 [信息]:使用 cpu 功能:MMX2 SSE2Fast SSSE3 FastShuffle SSE4.2 AVX

x264 [信息]:配置文件高,2.1 级

x264 [警告]:无效 DTS:PTS 小于 DTS

x264 [警告]:无效 DTS:PTS 小于 DTS

x264 [警告]:无效 DTS:PTS 小于 DTS

[0x7f90bb2456c0] 主 vout 显示错误:无法调整显示大小

[0x7f90bb2456c0] 主 vout 显示错误:无法设置在顶部

[h264 @ 0x7f90b4064020] mmco: unref 短故障

[h264 @ 0x7f90b4064620] mmco: unref 短故障

[h264 @ 0x7f90b4063a20] mmco: unref 短故障

[h264 @ 0x7f90b4063a20] mmco: unref 短故障

任何帮助将非常感激!此外,如果有一种“更清洁”的方式来整理我的“SetupVLC”代码,那么我会全力以赴。

谢谢!

4

1 回答 1

0

像这样进行转码时,您需要在媒体播放完毕后调用媒体播放器上的 release(),以便正确刷新本机缓冲区并正确关闭文件。

于 2013-09-27T07:38:02.003 回答