All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gstreamer.swing.VideoPlayer Maven / Gradle / Ivy

There is a newer version: 1.6
Show newest version
/* 
 * Copyright (c) 2007 Wayne Meissner
 * 
 * This file is part of gstreamer-java.
 *
 * This code is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License version 3 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
 * version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with this work.  If not, see .
 */

package org.gstreamer.swing;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import javax.swing.AbstractAction;
import javax.swing.BoundedRangeModel;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.gstreamer.State;
import org.gstreamer.media.PlayBinMediaPlayer;
import org.gstreamer.media.MediaPlayer;
import org.gstreamer.media.event.EndOfMediaEvent;
import org.gstreamer.media.event.MediaAdapter;
import org.gstreamer.media.event.MediaListener;
import org.gstreamer.media.event.StartEvent;
import org.gstreamer.media.event.StopEvent;

import com.sun.jna.Platform;

/**
 *
 */
public class VideoPlayer extends javax.swing.JPanel {
    
    private static final long serialVersionUID = 1964694975227372646L;
    private static final SwingExecutorService swingExec = new SwingExecutorService();

    public VideoPlayer(MediaPlayer player) {
        mediaPlayer = player;
        videoComponent = new VideoComponent();
        mediaPlayer.setVideoSink(videoComponent.getElement());
        setLayout(new BorderLayout());
        add(videoComponent, BorderLayout.CENTER);
        controls = new JPanel();
        controls.setLayout(new BoxLayout(controls, BoxLayout.X_AXIS));
        add(controls, BorderLayout.SOUTH);
        
        controls.add(new PopupVolumeButton(volumeModel));
        controls.add(new JButton(rewAction));
        controls.add(new JButton(togglePlayAction));
        controls.add(new JButton(fwdAction));
        playAction.setEnabled(true);
        pauseAction.setEnabled(false);
        stopAction.setEnabled(false);
        
        Object paintValue = UIManager.put("Slider.paintValue", Boolean.FALSE);
        controls.add(new JSlider(positionModel = new PipelinePositionModel(mediaPlayer.getPipeline())));
        
        UIManager.put("Slider.paintValue", paintValue);
        
        controls.add(positionLabel = new JLabel("00:00:00"));
        //
        // On MacOSX, need a spacer so the window resize control is visible
        //
        if (Platform.isMac()) {
            Box spacer = Box.createHorizontalBox();
            spacer.add(Box.createHorizontalStrut(16));
            controls.add(spacer);
        }
        controls.setVisible(false);
        
        //
        // Add a listener to update the media position label
        //
        positionModel.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                BoundedRangeModel m = (BoundedRangeModel)e.getSource();
                int value = m.getValue();
                String text = String.format("%02d:%02d:%02d", value / 3600, (value / 60) % 60, value % 60);
                positionLabel.setText(text);
            }
        });
        mediaPlayer.addMediaListener(swingExec.wrap(MediaListener.class, mediaListener));
        // Propate key events to the video component without giving it focus
        addKeyListener(new KeyAdapter() {

            public void keyPressed(KeyEvent evt) {
                for (KeyListener l : videoComponent.getKeyListeners()) {
                    l.keyPressed(evt);
                }
            }

            @Override
            public void keyReleased(KeyEvent evt) {
                for (KeyListener l : videoComponent.getKeyListeners()) {
                    l.keyReleased(evt);
                }
            }
        });
    }
    public VideoPlayer(File file) {
        this(file.toURI());
    }
    public VideoPlayer(String uri) {
        this(parseURI(uri));
    }
    public VideoPlayer(URI uri) {
        this(new PlayBinMediaPlayer("swing player", swingExec));
        mediaPlayer.setURI(uri);
    }
    private static URI parseURI(String uri) {
        try {
            URI u = new URI(uri);
            if (u.getScheme() == null) {
                throw new URISyntaxException(uri, "Invalid URI scheme");
            }
            return u;
        } catch (URISyntaxException e) {
            File f = new File(uri);
            if (!f.exists()) {
                throw new IllegalArgumentException("Invalid URI/file " + uri, e);
            }
            return f.toURI();
        }
    }
    public VideoComponent getVideoComponent() {
        return videoComponent;
    }
    public void setOpacity(float alpha) {
        float[] c = getBackground().getColorComponents(new float[3]);
        setBackground(new Color(c[0], c[1], c[2], alpha));
        videoComponent.setOpacity(alpha);
    }
    public float getOpacity() {
        return videoComponent.getOpacity();
    }
    
    @Override
    public void setOpaque(boolean isOpaque) {
        super.setOpaque(isOpaque);
        if (videoComponent != null) {
            videoComponent.setOpaque(isOpaque);
        }
    }
    
    public void setKeepAspect(boolean keepAspect) {
        videoComponent.setKeepAspect(keepAspect);
    }
    public void setControlsVisible(boolean visible) {
        controls.setVisible(visible);
        revalidate();
    }
    
    public void setURI(URI uri) {
        mediaPlayer.setURI(uri);
    }
    public void setInputFile(File file) {
        mediaPlayer.setURI(file.toURI());
    }
    
    /**
     * Obtain the MediaPlayer instance used by this VideoPlayer
     * @return The MediaPlayer used
     */
    public MediaPlayer getMediaPlayer() {
        return mediaPlayer;
    }
    
    ImageIcon playIcon = loadIcon("actions/media-playback-start");
    ImageIcon pauseIcon = loadIcon("actions/media-playback-pause");
    ImageIcon stopIcon = loadIcon("actions/media-playback-stop");
    ImageIcon fwdIcon = loadIcon("actions/media-seek-forward");
    ImageIcon rewIcon = loadIcon("actions/media-seek-backward");
    
    private AbstractAction playAction = new AbstractAction("", playIcon) {

        private static final long serialVersionUID = 1714683114563367993L;

        public void actionPerformed(ActionEvent e) {
            mediaPlayer.play();
        }
    };
    private AbstractAction pauseAction = new AbstractAction("", pauseIcon) {

        private static final long serialVersionUID = 1045795748586088103L;

        public void actionPerformed(ActionEvent e) {
            mediaPlayer.pause();
        }
    };
    private AbstractAction stopAction = new AbstractAction("", stopIcon) {

        private static final long serialVersionUID = 881154743003615413L;

        public void actionPerformed(ActionEvent e) {
            mediaPlayer.stop();
        }
    };
    private AbstractAction fwdAction = new AbstractAction("", fwdIcon) {

        private static final long serialVersionUID = -6661129153122209564L;

        public void actionPerformed(ActionEvent e) {
            positionModel.setValue(positionModel.getValue() + 60);
        }
    };
    private AbstractAction rewAction = new AbstractAction("", rewIcon) {

        private static final long serialVersionUID = 4450598460336990513L;

        public void actionPerformed(ActionEvent e) {
            positionModel.setValue(positionModel.getValue() - 60);
        }
    };
    
    private class TogglePlayAction extends AbstractAction {

        private static final long serialVersionUID = -333774735255804279L;

        public TogglePlayAction() {
            super("", pauseIcon);
        }
        public void setState(State state) {
            switch (state) {
            case PAUSED:
            case NULL:
                putValue(SMALL_ICON, playIcon);
                break;
            case PLAYING:
            default:
                putValue(SMALL_ICON, pauseIcon);
                break;
            }
        }
        public void actionPerformed(ActionEvent e) {
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();
                setState(State.PAUSED);
            } else {
                mediaPlayer.play();
                setState(State.PLAYING);
            }
        }
    }
    private MediaListener mediaListener = new MediaAdapter() {

        @Override
        public void endOfMedia(EndOfMediaEvent evt) {
            this.stop(evt);
        }

        @Override
        public void pause(StopEvent evt) {
            pauseAction.setEnabled(false);
            playAction.setEnabled(true);
            togglePlayAction.setState(State.PAUSED);
        }

        @Override
        public void start(StartEvent evt) {
            playAction.setEnabled(false);
            pauseAction.setEnabled(true);
            stopAction.setEnabled(true);
            togglePlayAction.setState(State.PLAYING);
        }

        @Override
        public void stop(StopEvent evt) {
            playAction.setEnabled(true);
            pauseAction.setEnabled(false);
            stopAction.setEnabled(false);
            togglePlayAction.setState(State.NULL);
        }
        
    };
    private TogglePlayAction togglePlayAction = new TogglePlayAction();
    private static ImageIcon loadIcon(String name) {
        return loadIcon(16, name);
    }
    private static ImageIcon loadIcon(int size, String name) {
        String path = "/org/freedesktop/tango/" + size + "x" + size + "/" + name + ".png";
        URL url = VideoPlayer.class.getResource(path);
        if (url != null) {
            return new ImageIcon(url);
        } else {
            throw new RuntimeException("Cannot locate icon for " + name);
        }
    }
    
    private BoundedRangeModel volumeModel = new DefaultBoundedRangeModel() {

        private static final long serialVersionUID = -4728390119456427400L;

        @Override
        public int getMaximum() {
            return 100;
        }

        @Override
        public int getMinimum() {
            return 0;
        }

        @Override
        public int getValue() {
            return Math.min(100, (int) ((mediaPlayer.getVolume() * 100d) + 0.5));
        }

        @Override
        public void setValue(int percent) {
            double volume = Math.max(Math.min((double) percent, 100d), 0d) / 100.0d;
            mediaPlayer.setVolume(volume);
        }
        
    };
    PipelinePositionModel positionModel;
    private MediaPlayer mediaPlayer;
    private JComponent controls;
    private JLabel positionLabel;
    private VideoComponent videoComponent;    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy