Révision 2436

tmp/org.txm.backtomedia.rcp/vlcj-4.1.0/pom.xml (revision 2436)
1
<!--
2
    vlcj pom.
3

  
4
    Add the following content to your own project pom.xml file:
5

  
6
    <dependencies>
7
        <dependency>
8
            <groupId>uk.co.caprica</groupId>
9
            <artifactId>vlcj</artifactId>
10
            <version>4.1.0</version>
11
        </dependency>
12
    </dependencies> 
13
-->
14

  
15
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
16

  
17
    <modelVersion>4.0.0</modelVersion>
18

  
19
    <parent>
20
        <groupId>org.sonatype.oss</groupId>
21
        <artifactId>oss-parent</artifactId>
22
        <version>9</version>
23
    </parent>
24

  
25
    <groupId>uk.co.caprica</groupId>
26
    <artifactId>vlcj</artifactId>
27
    <version>4.1.0</version>
28

  
29
    <name>vlcj</name>
30
    <description>Java Framework for the vlc Media Player.</description>
31
    <url>http://capricasoftware.co.uk/projects/vlcj</url>
32
    <inceptionYear>2009</inceptionYear>
33

  
34
    <packaging>jar</packaging>
35

  
36
    <licenses>
37
        <license>
38
            <name>GPL v3</name>
39
            <url>http://www.gnu.org/licenses/gpl-3.0.html</url>
40
            <distribution>repo</distribution>
41
        </license>
42
    </licenses>
43

  
44
    <organization>
45
        <name>Caprica Software Limited</name>
46
        <url>http://www.capricasoftware.co.uk</url>
47
    </organization>
48

  
49
    <developers>
50
        <developer>
51
            <id>mark</id>
52
            <name>Mark Lee</name>
53
            <email>mark.lee@capricasoftware.co.uk</email>
54
            <url>https://github.com/caprica/vlcj</url>
55
            <organization>Caprica Software Limited</organization>
56
            <organizationUrl>http://www.capricasoftware.co.uk</organizationUrl>
57
            <roles>
58
                <role>architect</role>
59
                <role>developer</role>
60
                <role>owner</role>
61
            </roles>
62
            <timezone>0</timezone>
63
        </developer>
64
    </developers>
65

  
66
    <issueManagement>
67
        <system>Github</system>
68
        <url>https://github.com/caprica/vlcj/issues</url>
69
    </issueManagement>
70

  
71
    <scm>
72
        <connection>scm:git:git@github.com:caprica/vlcj.git</connection>
73
        <developerConnection>scm:git:git@github.com:caprica/vlcj.git</developerConnection>
74
        <url>git@github.com:caprica/vlcj.git</url>
75
    </scm>
76

  
77
    <properties>
78
        <vlcjNatives.version>4.1.0</vlcjNatives.version>
79
        <vlcjOsxStubs.version>1.0.0</vlcjOsxStubs.version>
80
    </properties>
81

  
82
    <dependencies>
83
        <dependency>
84
            <groupId>uk.co.caprica</groupId>
85
            <artifactId>vlcj-natives</artifactId>
86
            <version>${vlcjNatives.version}</version>
87
        </dependency>
88
        <dependency>
89
            <groupId>uk.co.caprica</groupId>
90
            <artifactId>vlcj-osx-stubs</artifactId>
91
            <version>${vlcjOsxStubs.version}</version>
92
            <scope>provided</scope>
93
        </dependency>
94
    </dependencies>
95

  
96
    <build>
97
        <pluginManagement>
98
            <plugins>
99
                <plugin>
100
                    <groupId>org.eclipse.m2e</groupId>
101
                    <artifactId>lifecycle-mapping</artifactId>
102
                    <version>1.0.0</version>
103
                    <configuration>
104
                        <lifecycleMappingMetadata>
105
                            <pluginExecutions>
106
                                <pluginExecution>
107
                                    <pluginExecutionFilter>
108
                                        <groupId>org.apache.maven.plugins</groupId>
109
                                        <artifactId>maven-enforcer-plugin</artifactId>
110
                                        <versionRange>[1.0.0,)</versionRange>
111
                                        <goals>
112
                                            <goal>enforce</goal>
113
                                        </goals>
114
                                    </pluginExecutionFilter>
115
                                    <action>
116
                                        <ignore />
117
                                    </action>
118
                                </pluginExecution>
119
                            </pluginExecutions>
120
                        </lifecycleMappingMetadata>
121
                    </configuration>
122
                </plugin>
123
            </plugins>
124
        </pluginManagement>
125
        <plugins>
126
            <plugin>
127
                <groupId>org.apache.maven.plugins</groupId>
128
                <artifactId>maven-resources-plugin</artifactId>
129
                <version>3.1.0</version>
130
                <configuration>
131
                    <encoding>UTF-8</encoding>
132
                </configuration>
133
            </plugin>
134
            <plugin>
135
                <groupId>org.apache.maven.plugins</groupId>
136
                <artifactId>maven-compiler-plugin</artifactId>
137
                <version>3.8.0</version>
138
                <configuration>
139
                    <source>1.6</source>
140
                    <target>1.6</target>
141
                    <encoding>UTF-8</encoding>
142
                    <compilerArgument>-Xlint:serial</compilerArgument>
143
                </configuration>
144
            </plugin>
145
            <plugin>
146
                <groupId>org.apache.maven.plugins</groupId>
147
                <artifactId>maven-jar-plugin</artifactId>
148
                <version>3.1.1</version>
149
                <configuration>
150
                    <archive>
151
                        <manifest>
152
                            <addClasspath>true</addClasspath>
153
                        </manifest>
154
                    </archive>
155
                </configuration>
156
                <executions> 
157
                    <execution>
158
                        <goals> 
159
                            <goal>test-jar</goal>
160
                        </goals>
161
                        <configuration>
162
                            <useDefaultManifestFile>false</useDefaultManifestFile>
163
                            <archive>
164
                                <addMavenDescriptor>false</addMavenDescriptor>
165
                                <manifestEntries>
166
                                    <Class-Path>${project.artifactId}-${project.version}.jar</Class-Path>
167
                                </manifestEntries>
168
                            </archive>
169
                        </configuration>
170
                    </execution>
171
                </executions>
172
            </plugin>
173
            <plugin>
174
                <groupId>org.apache.maven.plugins</groupId>
175
                <artifactId>maven-source-plugin</artifactId>
176
                <version>3.0.1</version>
177
                <executions>
178
                    <execution>
179
                        <id>attach-sources</id>
180
                        <goals>
181
                            <goal>jar-no-fork</goal>
182
                            <goal>test-jar-no-fork</goal>
183
                        </goals>
184
                    </execution>
185
                </executions>
186
            </plugin>
187
            <plugin>
188
                <groupId>org.apache.maven.plugins</groupId>
189
                <artifactId>maven-javadoc-plugin</artifactId>
190
                <version>3.0.1</version>
191
                <configuration>
192
                    <author>true</author>
193
                    <charset>UTF-8</charset>
194
                    <doctitle>${project.name} ${project.version} API Documentation</doctitle>
195
                    <docfilessubdirs>true</docfilessubdirs>
196
                    <encoding>UTF-8</encoding>
197
                    <footer>(C)2019 Caprica Software Limited</footer>
198
                    <show>public</show>
199
                    <quiet>true</quiet>
200
                    <failOnError>true</failOnError>
201
                    <additionalOptions>-html5</additionalOptions>
202
                </configuration>
203
                <executions>
204
                    <execution>
205
                        <id>attach-javadocs</id>
206
                        <goals>
207
                            <goal>jar</goal>
208
                        </goals>
209
                    </execution>
210
                </executions>
211
            </plugin>
212
            <plugin>
213
                <groupId>org.apache.maven.plugins</groupId>
214
                <artifactId>maven-assembly-plugin</artifactId>
215
                <version>3.1.0</version>
216
                <configuration>
217
                    <attach>false</attach>
218
                </configuration>
219
                <executions>
220
                    <execution>
221
                        <id>user_distribution</id>
222
                        <phase>package</phase>
223
                        <goals>
224
                            <goal>single</goal>
225
                        </goals>
226
                        <configuration>
227
                            <descriptors>
228
                                <descriptor>src/main/assembly/dist.xml</descriptor>
229
                            </descriptors>
230
                        </configuration>
231
                    </execution>
232
                </executions>
233
            </plugin>
234
            <plugin>
235
                <groupId>org.apache.maven.plugins</groupId>
236
                <artifactId>maven-dependency-plugin</artifactId>
237
                <version>3.1.1</version>
238
                <executions>
239
                    <execution>
240
                        <id>copy-dependencies</id>
241
                        <phase>package</phase>
242
                        <goals>
243
                            <goal>copy-dependencies</goal>
244
                        </goals>
245
                        <configuration>
246
                            <includeScope>runtime</includeScope>
247
                            <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
248
                            <overWriteReleases>false</overWriteReleases>
249
                            <overWriteSnapshots>false</overWriteSnapshots>
250
                            <overWriteIfNewer>true</overWriteIfNewer>
251
                        </configuration>
252
                    </execution>
253
                </executions>
254
            </plugin>
255
            <plugin>
256
                <artifactId>jdeb</artifactId>
257
                <groupId>org.vafer</groupId>
258
                <version>1.7</version>
259
                <executions>
260
                    <execution>
261
                        <phase>package</phase>
262
                        <goals>
263
                            <goal>jdeb</goal>
264
                        </goals>
265
                        <configuration>
266
                            <verbose>true</verbose>
267
                            <dataSet>
268
                                <data>
269
                                    <src>${project.build.directory}/${project.build.finalName}.jar</src>
270
                                    <type>file</type>
271
                                    <mapper>
272
                                        <type>perm</type>
273
                                        <prefix>/usr/share/vlcj/lib</prefix>
274
                                    </mapper>
275
                                </data>
276
                                <data>
277
                                    <src>${project.build.directory}/dependencies</src>
278
                                    <type>directory</type>
279
                                    <mapper>
280
                                        <type>perm</type>
281
                                        <prefix>/usr/share/vlcj/lib</prefix>
282
                                    </mapper>
283
                                </data>
284
                                <data>
285
                                    <src>README.md</src>
286
                                    <type>file</type>
287
                                    <mapper>
288
                                        <type>perm</type>
289
                                        <prefix>/usr/share/doc/vlcj</prefix>
290
                                    </mapper>
291
                                </data>
292
                                <data>
293
                                    <src>doc/copyright</src>
294
                                    <type>file</type>
295
                                    <mapper>
296
                                        <type>perm</type>
297
                                        <prefix>/usr/share/doc/vlcj</prefix>
298
                                    </mapper>
299
                                </data>
300
                            </dataSet>
301
                        </configuration>
302
                    </execution>
303
                </executions>
304
            </plugin>
305
        </plugins>
306
        <resources>
307
            <resource>
308
                <directory>src/main/resources</directory>
309
                <filtering>true</filtering>
310
                <excludes>
311
                    <exclude>.gitignore</exclude>
312
                </excludes>
313
            </resource>
314
        </resources>
315
    </build>
316

  
317
</project>
tmp/org.txm.backtomedia.rcp/vlcj-4.1.0/README.md (revision 2436)
1
![vlcj](https://github.com/caprica/vlcj/raw/master/etc/vlcj-logo.png "vlcj")
2

  
3
*You are currently looking at the development branch for vlcj-4.0.0, if you are looking for the previous version of vlcj
4
you should switch to the [vlcj-3.x branch](https://github.com/caprica/vlcj/tree/vlcj-3.x).* 
5

  
6
vlcj
7
====
8

  
9
The vlcj project provides a Java framework to allow an instance of a native [VLC](http://www.videolan.org/vlc "VLC")
10
media player to be embedded in a Java application.
11

  
12
You get more than just simple bindings, you also get a higher level framework that hides a lot of the complexities of
13
working with LibVLC.
14

  
15
vlcj is primarily developed and therefore extensively tested on Linux - it does also work just fine on Windows and
16
OSX, although there may be some limitations on OSX.
17

  
18
Additionally, whilst not supported as one of the main platforms, this version of vlcj has been tested and shown to be
19
working on contemporary Raspberry Pi builds.
20

  
21
At least JDK 1.6 is required.
22

  
23
*This version of vlcj requires VLC 3.0.0 as a minimum, no earlier version is supported.*
24

  
25
This is the open source vlcj project page, see also the 'official'
26
[home page](http://capricasoftware.co.uk/projects/vlcj "Official vlcj home page at Caprica Software") where you can find
27
more information as well as some new simple tutorials.
28

  
29
News
30
====
31

  
32
- 5th April, 2019 - vlcj 4.1.0 release, this release brings JNA "direct mapping" which should give a modest performance boost
33
- 1st April, 2019 - vlcj 4.0.8 released, fixes an issue with the BufferedImage in the CallbackMediaPlayerComponent
34
- 24th March, 2019 - vlcj 4.0.7 released, minor change to allow to change the callback video surface image painter after creation
35
- 18th March, 2019 - published a Yeoman generator for vlcj starter projects, see [generator-vlcj](https://github.com/caprica/generator-vlcj)
36
- 5th March, 2019 - vlcj 4.0.6 released, fixes issues with image painters when using CallbackMediaPlayerComponent
37
- 4th March, 2019 - vlcj 4.0.5 released, fixes a problem using ByteBuffer on Java8
38
- 4th March, 2019 - vlcj 4.0.4 released, audio callbacks can now optionally manage audio volume, some minor API changes
39
- 1st March, 2019 - vlcj 4.0.3 released, fixes a problem with native discovery directory providers and minor API changes
40
- 28th February, 2019 - vlcj 4.0.2 released, resolves a potential deadlock (upgrade to this version strongly recommended)
41
- 27th February, 2019 - vlcj 4.0.1 released, primarily fixes a small number of minor public API issues
42
- 20th February, 2019 - vlcj 4.0.0 released
43

  
44
All releases are at available at [Maven Central](https://search.maven.org/search?q=a:vlcj).
45

  
46
You can follow @capricasoftware on Twitter for more vlcj news.
47

  
48
vlcj-4
49
======
50

  
51
vlcj-4 has a new API, but there is still a lot of similarity with vlcj-3 and under the covers there is still mostly the
52
same mature and stable implementation.
53

  
54
The vlcj-4 API is now pretty much stable, although some changes may be made depending on feedback and usage after the
55
first release of 4.0.0 is let loose into the wild - but no further *major* API changes are planned or expected.
56

  
57
If you are interested in using vlcj-4, now is a good time to start.
58

  
59
vlcj-4.1
60
========
61

  
62
vlcj-4.1 brings JNA "direct mapping" which should give a modest performance boost at the expense of less helpful error
63
messages if things go wrong when loading the native LibVLC library.
64

  
65
If you wish to stay with "traditional" JNA bindings, then stick with the latest vlcj-4.0.x.
66

  
67
This direct mapping approach will be used in all future versions of vlcj, meaning vlcj-4.1.x, vlcj-5.x and later.
68

  
69
Major New Features
70
------------------
71

  
72
Headline changes:
73

  
74
 - full support for 360 degree video, changing pitch, yaw, roll, field-of-view
75
 - full support for discovery and usage of alternate media renderers, e.g. Chromecast
76
 - full support for media-slave API to set subtitle tracks and additional/alternate audio tracks
77
 - full support for integrated native dialogs, e.g. you can now be prompted for credentials when accessing a protected
78
   stream
79
 - use any AWT Component as a video surface, not just a Canvas (Window will work on OSX, with limitations)
80
 - easy to add support for alternate video surfaces, e.g. an SWT Composite
81
 - major changes and improvements to the so-called "direct-rendering" media players, the direct audio and video media
82
   players are no longer separate components and are now instead intrinsic to the standard media player. For video, a
83
   new "Callback" video surface brings a vastly improved implementation, an optional related component provides a good
84
   default implementation for direct-rendering and an easy way to deal with re-sizing of the video, with easy extension
85
   points for custom video "painters"
86
 - improvements to full-screen support with sensible default implementations provided for Linux, Windows and OSX, all
87
   using a native solution to provide the best result
88
 - automatic handling of subitems (e.g. when playing a YouTube video or a streaming playlist) is now intrinsic to the
89
   media player and requires no involvement of the client application
90
 - simplified native library discovery, now intrinsic to the media player factory and it should just work out-of-the-box
91
   in the vast majority of cases
92
 - API support for multiple logos (in series, not concurrent)
93
 - logo and marquee now work without having to explicitly enable the respective native modules
94
 - there is now better support for media generally (e.g. using media without a media player, for parsing meta data etc),
95
   and also better support for media-lists (e.g. it should now be easier to manage your own play-lists)
96

  
97
There have also been a lot of more general improvements to freshen up the codebase, make it more maintainable for the
98
future, and to clear some legacy issues that have dogged the project for quite some time.
99

  
100
For a full list of changes in this release, check the release milestones:
101

  
102
- [vlcj 4.0.0 release milestone](https://github.com/caprica/vlcj/milestone/14?closed=1)
103
- [vlcj 4.0.1 release milestone](https://github.com/caprica/vlcj/milestone/32?closed=1)
104
- [vlcj 4.0.2 release milestone](https://github.com/caprica/vlcj/milestone/33?closed=1)
105
- [vlcj 4.0.3 release milestone](https://github.com/caprica/vlcj/milestone/34?closed=1)
106
- [vlcj 4.0.4 release milestone](https://github.com/caprica/vlcj/milestone/35?closed=1)
107
- [vlcj 4.0.5 release milestone](https://github.com/caprica/vlcj/milestone/36?closed=1)
108
- [vlcj 4.0.6 release milestone](https://github.com/caprica/vlcj/milestone/37?closed=1)
109
- [vlcj 4.0.7 release milestone](https://github.com/caprica/vlcj/milestone/38?closed=1)
110
- [vlcj 4.0.8 release milestone](https://github.com/caprica/vlcj/milestone/40?closed=1)
111

  
112
vlcj 4.1.0+ uses JNA direct-mapping:
113

  
114
- [vlcj 4.1.0 release milestone](https://github.com/caprica/vlcj/milestone/39?closed=1)
115

  
116
Despite all of these changes, running on JDK 1.6 is still supported!
117

  
118
Known Issues
119
------------
120

  
121
 - `CallbackMediaPlayerComponent` does not properly render media that does not have a sample-aspect-ratio (SAR) 1:1,
122
   this mostly affects DVD ISO, you can still provide your own implementation that handles other SAR's if you need to.
123
   In any case, using the callback media player with DVD ISO is somewhat of a niche combination and for the vast
124
   majority of media types this will not be an issue. This may be improved in a later release. The fundamental problem
125
   right now is that there is simply no *reliable* way to know the SAR - SAR does appear eventually in track information
126
   but there is no concrete link between that SAR track information and the currently playing video track. This is an
127
   issue in the underlying native library.
128

  
129
 - When using the new alternate renderer API, if you attempt to play another media while a media is already being sent
130
   to something like Chromecast you may experience problems - even if you stop the current media first. The cause of
131
   this is currently unknown, but it may be a native issue.
132

  
133
API Breakage (vlcj-3)
134
---------------------
135

  
136
This is the *tenth year* of the project, the API has been pretty much static for that entire time. The codebase has
137
evolved gradually and incrementally in that time and resulted sometimes in sub-optimal implementations and choices, as
138
well as some generally unwieldy individual classes containing literally thousands of lines of code. Keeping the API
139
fixed for those almost ten years also locked in some long-standing architectural issues that simply could not be
140
resolved.
141

  
142
The decision to break backwards compatibility with the vlcj-3 API was not taken lightly, but the results have been worth
143
it. All legacy architectural issues have been resolved, the giant god-classes have been factored to more manageable
144
chunks, and ongoing maintenance will be much easier.
145

  
146
The price for these improvements is some API breakage, sorry.
147

  
148
The short version of the situation is that vlcj-4 can *not* be considered a drop-in upgrade for any vlcj-3 applications.
149
If you want to move to vlcj-4 with your existing applications, you *will* be impacted, at best you will need to use new
150
names for existing methods, at worst although very unlikely you may have to make some *deep* changes in your own
151
codebase. 
152

  
153
There is no automatic migration tool.
154

  
155
The longer version of the situation is documented more fully in
156
[this ticket](https://github.com/caprica/vlcj/issues/681). 
157

  
158
Tutorials
159
---------
160

  
161
New tutorials for vlcj-4 are available [here](http://capricasoftware.co.uk/projects/vlcj-4/tutorials).
162

  
163
There are simple tests or demo applications available for pretty much every aspect of vlcj functionality, these are
164
provided in the
165
[project test sources](https://github.com/caprica/vlcj/tree/master/src/test/java/uk/co/caprica/vlcj/test).
166

  
167
There is also a major demo application available at the [vlcj-player](https://github.com/caprica/vlcj-player) project
168
page.
169

  
170
Building vlcj - sun.misc.Unsafe
171
-------------------------------
172

  
173
Currently the target supported JDK is still 1.6, since there are no new language or platform features used in vlcj
174
that need anything past 1.6. There is no particularly strong reason to keep supporting 1.6, but there is no particular
175
reason to abandon it either.
176

  
177
On the other hand, the project is at the moment built with OpenJDK 11 on Linux and cross-compiled to 1.6. This will
178
work just fine when using Maven to build the project from the command-line, or when working with Eclipse.
179

  
180
However, if you use IntelliJ IDEA you may encounter some compilation problems...
181

  
182
When compiling, IDEA will complain that package sun.misc does not exist - the `Unsafe` class from this package is
183
required for the "direct" media players.
184

  
185
This can be worked around in a number of ways:
186

  
187
 - use source and target JDK 1.10 in the pom.xml, which IDEA will then incorporate into the project
188
 - use JDK 1.9 and convert the project to use the Java Module System and add jdk.unsupported as a required module
189
 - change the IDEA compiler settings to *uncheck* the "Use '--release' option for cross-compilation (Java 9 and later)"
190

  
191
The latter option is probably the simplest to deal with.
192

  
193
When compiling with Maven it is simply not possible to suppress the warnings about using sun.misc.Unsafe.
194

  
195
Maven Dependency
196
----------------
197

  
198
Add the following Maven dependency to your own project pom.xml:
199

  
200
```
201
<dependency>
202
    <groupId>uk.co.caprica</groupId>
203
    <artifactId>vlcj</artifactId>
204
    <version>4.1.0</version>
205
</dependency>
206
```
207

  
208
The core vlcj project now no longer contains the required JNA bindings to LibVLC, these are provided instead by the
209
separate [vlcj-natives](https://github.com/caprica/vlcj-natives) project. The vlcj core project therefore has a new
210
required dependency on the vlcj-natives project.
211

  
212
If you are using Maven (or similar) to manage your dependencies, the vlcj-natives dependency will be handled
213
automatically for you (you only need to explicitly add vlcj to your project, not vlcj-natives).
214

  
215
If you are installing vlcj manually, then you will need to include the new vlcj-natives jar file along with the existing
216
vlcj jar file.
217

  
218
Threading Model
219
---------------
220

  
221
This section is very important.
222

  
223
With vlcj-4, every native event coming from LibVLC is processed on the native callback thread. This should give some
224
small performance gains when compared with vlcj-3.
225

  
226
The critical issue is that it is generally not permitted to call back into LibVLC from the event callback thread. Doing
227
so may cause subtle failures or outright hard JVM crashes.
228

  
229
A prime example of the sort of trap waiting for you is the very common case of handling a media player "finished" event
230
so that you can then play the next item in a play-list:
231

  
232
```
233
mediaPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
234
    @Override
235
    public void finished(MediaPlayer mediaPlayer) {
236
        mediaPlayer.media().play(nextMrl); // <-- This is VERY BAD INDEED
237
    }
238
});
239
```
240

  
241
In this example, the `finished` method is being invoked on a native callback thread owned by LibVLC. The implementation
242
of this method is calling back into LibVLC when it invokes `play`. This is very likely to cause a JVM crash and
243
kill your application.
244

  
245
In cases such as this, you should make use of an asynchronous task-executor queue conveniently provided by the 
246
`MediaPlayer` object passed to the listener method:
247

  
248
```
249
mediaPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
250
    @Override
251
    public void finished(final MediaPlayer mediaPlayer) {
252
        mediaPlayer.submit(new Runnable() {
253
            @Override
254
            public void run() {
255
                mediaPlayer.media().play(nextMrl);
256
            }
257
        });
258
    }
259
});
260
```
261

  
262
You should *not* use this mechanism for *all* of your event handlers, *only those that will call back into LibVLC*.
263

  
264
Other high-level vlcj components may also provide their own asynchronous task executor, it is not limited to the media
265
player.
266

  
267
An added caveat for vlcj-4 is that when you implement event handling you must be sure to execute quickly, and to not
268
block the native thread with any long-running operation.
269

  
270
Your event handler implementations must *not* throw an `Exception`, failure of your event handlers to catch and handle
271
any thrown exception may prevent other listeners from being notified of the event.
272

  
273
If you are attempting to use multiple media players in your application, or using media players from multiple threads,
274
you may need to take some extra care so that you do not have multiple threads calling into LibVLC concurrently. You may
275
encounter subtle bugs and races that are very difficult to diagnose.
276

  
277
In addition, you must take care not to update Swing UI components from the native thread - all Swing UI updates are
278
supposed to go via the Swing Event Dispatch Thread (EDT).
279
 
280
You can achieve this in the usual way by using `SwingUtilities#invokeLater` in your event handler:
281

  
282
```
283
mediaPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
284
    @Override
285
    public void finished(MediaPlayer mediaPlayer) {
286
        SwingUtilities.invokeLater(new Runnable() {
287
            @Override
288
            public void run() {
289
                // ...change UI state here...
290
            }
291
        });
292
    }
293
});
294
```
295

  
296
Garbage Collection
297
------------------
298

  
299
This section is also very important.
300

  
301
Ordinarily when developing with Java you will be used to not thinking about the scope and life-cycle of the objects that
302
you create, instead you will rely on the garbage collector in the Java Virtual Machine to just take of things for you.
303

  
304
With vlcj's `MediaPlayerFactory`, `MediaPlayer`, and associated classes, you must take care to prevent those objects
305
from being garbage collected - if you do not, at best your media player will simply unexpectedly stop working and at
306
worst you may see a fatal JVM crash.
307

  
308
Those vlcj objects wrap a native resource (e.g. a native media player). Those media player resources know nothing about
309
any JVM. So just because a native media player is still "alive" it will not prevent your object instance from being
310
garbage collected. If your object instance does get garbage collected, the native resource still has no idea, and will
311
will keeping sending native events back to the JVM via a callback. If your object is gone, that native callback has
312
nowhere to go and will most likely crash your JVM.
313

  
314
A very common mistake is to declare vlcj objects on the local heap in some sort of initialisation method:
315

  
316
```
317
    private void setup() {
318
        MediaPlayerFactory factory = new MediaPlayerFactory();
319
        EmbeddedMediaPlayer mediaPlayer = factory.mediaPlayers().newEmbeddedMediaPlayer();
320
        // ... other initialisation ...
321
    }
322
```
323

  
324
When this method returns, the `factory` and `mediaPlayer` objects go out of scope and become eligible for garbage
325
collection. The garbage collection may happen immediately, or some time later.
326

  
327
The most common solution is to change those local heap declarations to class fields:
328

  
329
```
330
    private MediaPlayerFactory factory;
331

  
332
    private EmbeddedMediaPlayer mediaPlayer;
333

  
334
    private void setup() {
335
        factory = new MediaPlayerFactory();
336
        mediaPlayer = factory.mediaPlayers().newEmbeddedMediaPlayer();
337
        // ... other initialisation ...
338
    }
339

  
340
```
341

  
342
This is fine and will work in most cases, but you must still make sure that the enclosing class does not itself get
343
garbage collected!
344

  
345
See this [vlcj garbage collection tutorial](http://capricasoftware.co.uk/projects/vlcj-4/tutorials/garbage-collection)
346
for more information.
347

  
348
Privacy Considerations
349
----------------------
350

  
351
When parsing media, depending on configuration, it may be possible that a remote network access is made for meta data
352
and album/cover art. This may unintentionally expose sensitive data regarding the media being parsed.
353

  
354
To affirmatively prevent all network access for meta data, consider using the `--no-metadata-network-access` argument
355
when creating a `MediaPlayerFactory`.
356

  
357
It should also be possible to prevent such network accesses by using appropriate `ParseFlag` values when requesting to
358
parse media.
359

  
360
Even with network access disabled, some media cover art may still appear locally (e.g. ~/.cache/vlc) - this does not
361
necessarily mean that a remote network request was made for the cover art, rather the art that was already embedded in
362
the media file was extracted to this temporary cache directory.
363

  
364
In any case, you need to be aware of this issue and inform users of your application about it.
365

  
366
Documentation
367
-------------
368

  
369
Tutorials will be made available, not yet, at the
370
[official project page](http://capricasoftware.co.uk/projects/vlcj/tutorials).
371

  
372
The vlcj project page is at [github](http://caprica.github.com/vlcj "vlcj at github").
373

  
374
Online Javadoc is available here:
375

  
376
JNA direct-mapping:
377

  
378
* [4.1.0 (current)](http://caprica.github.com/vlcj/javadoc/4.1.0/index.html "4.1.0 Javadoc")
379

  
380
JNA traditional mapping:
381

  
382
* [4.0.8 (current)](http://caprica.github.com/vlcj/javadoc/4.0.8/index.html "4.0.8 Javadoc")
383
* [4.0.7](http://caprica.github.com/vlcj/javadoc/4.0.7/index.html "4.0.7 Javadoc")
384
* [4.0.6](http://caprica.github.com/vlcj/javadoc/4.0.6/index.html "4.0.6 Javadoc")
385
* [4.0.5](http://caprica.github.com/vlcj/javadoc/4.0.5/index.html "4.0.5 Javadoc")
386
* [4.0.4](http://caprica.github.com/vlcj/javadoc/4.0.4/index.html "4.0.4 Javadoc")
387
* [4.0.3](http://caprica.github.com/vlcj/javadoc/4.0.3/index.html "4.0.3 Javadoc")
388
* [4.0.2](http://caprica.github.com/vlcj/javadoc/4.0.2/index.html "4.0.2 Javadoc")
389
* [4.0.1](http://caprica.github.com/vlcj/javadoc/4.0.1/index.html "4.0.1 Javadoc")
390
* [4.0.0](http://caprica.github.com/vlcj/javadoc/4.0.0/index.html "4.0.0 Javadoc")
391

  
392
Examples
393
--------
394

  
395
There are many examples in the vlcj test sources showing how to use vlcj.
396

  
397
For a more complete example of a feature-rich media player built with vlcj,
398
see [vlcj-player](https://github.com/caprica/vlcj-player).
399

  
400
Related Projects
401
----------------
402

  
403
 * [vlcj-natives](https://github.com/caprica/vlcj-natives)
404
 * [vlcj-player](https://github.com/caprica/vlcj-player)
405
 * [vlcj-javafx](https://github.com/caprica/vlcj-javafx)
406
 * [vlcj-mrls](https://github.com/caprica/vlcj-mrls)
407
 * [vlcj-file-filters](https://github.com/caprica/vlcj-file-filters)
408
 * [vlcj-swt](https://github.com/caprica/vlcj-swt)
409
 * [vlcj-swt-demo](https://github.com/caprica/vlcj-swt-demo)
410
 * [vlcj-swt-swing](https://github.com/caprica/vlcj-swt-swing)
411
 * [vlcj-info](https://github.com/caprica/vlcj-info)
412
 * [vlcj-radio-demo](https://github.com/caprica/vlcj-radio-demo)
413
 * [generator-vlcj](https://github.com/caprica/generator-vlcj)
414

  
415
Support
416
-------
417

  
418
Development of vlcj is carried out by [Caprica Software](http://www.capricasoftware.co.uk).
419

  
420
Free support for Open Source and non-commercial projects is generally provided - you can
421
use [github issues](https://github.com/caprica/vlcj/issues "vlcj github issues") for this purpose.
422

  
423
Support for commercial projects is provided exclusively on commercial terms - send an email to the following address for
424
more information:
425

  
426
> mark [dot] lee [at] capricasoftware [dot] co [dot] uk
427

  
428
License
429
-------
430

  
431
The vlcj framework is provided under the GPL, version 3 or later.
432

  
433
If you want to consider a commercial license for vlcj that allows you to use and redistribute vlcj without complying
434
with the GPL then send an email to the address below:
435

  
436
> mark [dot] lee [at] capricasoftware [dot] co [dot] uk
437

  
438
Contributors
439
------------
440

  
441
Contributions are welcome and will always be licensed according to the Open Source license terms of the project (currently GPL).
442

  
443
However, for a contribution to be accepted you must agree to transfer any copyright so that your contribution does not
444
impede our ability to provide commercial licenses for vlcj.
tmp/org.txm.backtomedia.rcp/vlcj-4.1.0/swt/SwtMediaPlayerFactory.java (revision 2436)
1
/*
2
 * This file is part of VLCJ.
3
 *
4
 * VLCJ is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * VLCJ is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with VLCJ.  If not, see <http://www.gnu.org/licenses/>.
16
 *
17
 * Copyright 2009-2019 Caprica Software Limited.
18
 */
19

  
20
package uk.co.caprica.vlcj.factory.swt;
21

  
22
import uk.co.caprica.vlcj.factory.discovery.NativeDiscovery;
23
import uk.co.caprica.vlcj.factory.MediaPlayerFactory;
24

  
25
import java.util.Collection;
26

  
27
// FIXME should we build an SwtEmbeddedMediaPlayerComponent that extends Composite, similar to how we extend JPanel for SWT?
28

  
29
/**
30
 * Extension to the default {@link MediaPlayerFactory} that provides SWT components.
31
 */
32
public class SwtMediaPlayerFactory extends MediaPlayerFactory {
33
	
34
	private final SwtApi swtApi;
35
	
36
	public SwtMediaPlayerFactory(NativeDiscovery discovery, String... libvlcArgs) {
37
		super(discovery, libvlcArgs);
38
		
39
		this.swtApi = new SwtApi(this);
40
	}
41
	
42
	public SwtMediaPlayerFactory(String... libvlcArgs) {
43
		this(null, libvlcArgs);
44
	}
45
	
46
	public SwtMediaPlayerFactory(NativeDiscovery discovery, Collection<String> libvlcArgs) {
47
		this(discovery, libvlcArgs.toArray(new String[libvlcArgs.size()]));
48
	}
49
	
50
	public SwtMediaPlayerFactory(Collection<String> libvlcArgs) {
51
		this(null, libvlcArgs.toArray(new String[libvlcArgs.size()]));
52
	}
53
	
54
	/**
55
	 *
56
	 *
57
	 * @return
58
	 */
59
	public final SwtApi swt() {
60
		return swtApi;
61
	}
62
	
63
	@Override
64
	public void onBeforeRelease() {
65
		swtApi.release();
66
	}
67
	
68
}
0 69

  
tmp/org.txm.backtomedia.rcp/vlcj-4.1.0/swt/BaseApi.java (revision 2436)
1
/*
2
 * This file is part of VLCJ.
3
 *
4
 * VLCJ is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * VLCJ is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with VLCJ.  If not, see <http://www.gnu.org/licenses/>.
16
 *
17
 * Copyright 2009-2019 Caprica Software Limited.
18
 */
19

  
20
package uk.co.caprica.vlcj.factory.swt;
21

  
22
abstract class BaseApi {
23
	
24
	protected final SwtMediaPlayerFactory factory;
25
	
26
	BaseApi(SwtMediaPlayerFactory factory) {
27
		this.factory = factory;
28
	}
29
	
30
	protected void release() {}
31
	
32
}
0 33

  
tmp/org.txm.backtomedia.rcp/vlcj-4.1.0/swt/SwtApi.java (revision 2436)
1
/*
2
 * This file is part of VLCJ.
3
 *
4
 * VLCJ is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * VLCJ is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with VLCJ.  If not, see <http://www.gnu.org/licenses/>.
16
 *
17
 * Copyright 2009-2019 Caprica Software Limited.
18
 */
19

  
20
package uk.co.caprica.vlcj.factory.swt;
21

  
22
import org.eclipse.swt.widgets.Composite;
23
import uk.co.caprica.vlcj.player.embedded.videosurface.VideoSurfaceAdapters;
24
import uk.co.caprica.vlcj.player.embedded.videosurface.swt.CompositeVideoSurface;
25

  
26
/**
27
 *
28
 */
29
public final class SwtApi extends BaseApi {
30
	
31
	/**
32
	 *
33
	 *
34
	 * @param mediaPlayerFactory
35
	 */
36
	public SwtApi(SwtMediaPlayerFactory mediaPlayerFactory) {
37
		super(mediaPlayerFactory);
38
	}
39
	
40
	/**
41
	 *
42
	 *
43
	 * @param composite
44
	 * @return
45
	 */
46
	public CompositeVideoSurface newCompositeVideoSurface(Composite composite) {
47
		return new CompositeVideoSurface(composite, VideoSurfaceAdapters.getVideoSurfaceAdapter());
48
	}
49
	
50
}
0 51

  
tmp/org.txm.backtomedia.rcp/vlcj-4.1.0/vlcplayer/VLCPlayer.java (revision 2436)
1
package org.txm.backtomedia.editors.vlcplayer;
2

  
3
import static uk.co.caprica.vlcj.binding.LibVlc.libvlc_new;
4
import static uk.co.caprica.vlcj.binding.LibVlc.libvlc_release;
5

  
6
import java.io.File;
7
import java.time.LocalTime;
8
import java.time.format.DateTimeFormatter;
9

  
10
import org.eclipse.osgi.util.NLS;
11
import org.eclipse.swt.SWT;
12
import org.eclipse.swt.events.DisposeEvent;
13
import org.eclipse.swt.events.DisposeListener;
14
import org.eclipse.swt.events.SelectionEvent;
15
import org.eclipse.swt.events.SelectionListener;
16
import org.eclipse.swt.layout.GridData;
17
import org.eclipse.swt.layout.GridLayout;
18
import org.eclipse.swt.widgets.Button;
19
import org.eclipse.swt.widgets.Composite;
20
import org.eclipse.swt.widgets.FileDialog;
21
import org.eclipse.swt.widgets.Label;
22
import org.eclipse.swt.widgets.Scale;
23
import org.txm.backtomedia.commands.function.TripleRangeSlider;
24
import org.txm.backtomedia.preferences.BackToMediaPreferences;
25
import org.txm.utils.logger.Log;
26

  
27
import com.sun.jna.StringArray;
28

  
29
import uk.co.caprica.vlcj.binding.LibC;
30
import uk.co.caprica.vlcj.binding.RuntimeUtil;
31
import uk.co.caprica.vlcj.binding.internal.libvlc_instance_t;
32
import uk.co.caprica.vlcj.factory.discovery.NativeDiscovery;
33
import uk.co.caprica.vlcj.factory.discovery.strategy.NativeDiscoveryStrategy;
34
import uk.co.caprica.vlcj.factory.swt.SwtMediaPlayerFactory;
35
import uk.co.caprica.vlcj.media.MediaRef;
36
import uk.co.caprica.vlcj.player.base.MediaPlayer;
37
import uk.co.caprica.vlcj.player.base.MediaPlayerEventAdapter;
38
import uk.co.caprica.vlcj.player.component.EmbeddedMediaPlayerComponent;
39
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
40
import uk.co.caprica.vlcj.player.embedded.videosurface.swt.CompositeVideoSurface;
41
import uk.co.caprica.vlcj.support.version.LibVlcVersion;
42
import vlcplayerrcp.MessagesMP;
43

  
44
public class VLCPlayer extends Composite {
45
	
46
	static { // force native libs discovery -> fix Mac OS X init
47
		NativeDiscovery discovery = new NativeDiscovery() {
48
			
49
			@Override
50
			protected void onFound(String path, NativeDiscoveryStrategy strategy) {
51
				Log.finer("VLC NativeDiscovery: onFound " + path + " " + strategy);
52
			}
53
			
54
			@Override
55
			protected void onNotFound() {
56
				Log.finer("VLC NativeDiscovery: Not found.");
57
			}
58
		};
59
		boolean found = discovery.discover();
60
		Log.finer("VLC NativeDiscovery: the discovery was succesfull ? " + found);
61
		if (found) {
62
			libvlc_instance_t instance = libvlc_new(0, new StringArray(new String[0]));
63
			Log.finer("VLC NativeDiscovery: VLC instance is " + instance);
64
			if (instance != null) {
65
				libvlc_release(instance);
66
			}
67
			else {
68
				Log.warning(NLS.bind("** Impossible to use your VLC [{0}] (please check that you have at least VLC version 3.0).", instance));
69
			}
70
			Log.finer("VLC NativeDiscovery: VLC version is " + new LibVlcVersion().getVersion());
71
		}
72
		else {
73
			Log.warning("** Impossible to find VLC (please check that you have at least VLC version 3.0).");
74
		}
75
	}
76
	
77
	protected static final String NOMEDIA = ""; //$NON-NLS-1$
78
	
79
	private EmbeddedMediaPlayer vlcPlayer;
80
	
81
	private Composite videoComposite;
82
	
83
	private CompositeVideoSurface playerCanvas;
84
	
85
	private Scale rateField;
86
	
87
	private Label rateValueLabel;
88
	
89
	private Scale volumeField;
90
	
91
	private Label volumeValueLabel;
92
	
93
	private Button playButton;
94
	
95
	private Button repeatButton;
96
	
97
	protected String currentlyPlayed = ""; //$NON-NLS-1$
98
	
99
	// private String startTime, endTime;
100
	private int start, end;
101
	
102
	protected boolean hasEnded = false;
103
	
104
	private String previouslyPlayed = ""; //$NON-NLS-1$
105
	
106
	private boolean repeat = false;
107
	
108
	protected int volume = 100;
109
	
110
	private Button stopButton;
111
	
112
	Label timeLabel;
113
	
114
	TripleRangeSlider timeRange;
115
	
116
	boolean firstLengthEvent = true;
117
	
118
	long previous = 0;
119
	
120
	long time, mins, secs;
121
	
122
	private SwtMediaPlayerFactory factory;
123
	
124
	
125
	static {
126
		// uncomment to enable VLC logs
127
		// Logger.setLevel(Level.TRACE);
128
	}
129
	
130
	public EmbeddedMediaPlayer getEmbeddedMediaPlayer() {
131
		return vlcPlayer;
132
	}
133
	
134
	public VLCPlayer(Composite parent, int style) {
135
		super(parent, style);
136
		this.setLayout(new GridLayout(11, false));
137
		
138
		// THE PLAYER
139
		// if (RuntimeUtil.isMac()) {
140
		// try {
141
		// LibC.INSTANCE.setenv("VLC_PLUGIN_PATH", "/Applications/VLC.app/Contents/MacOS/plugins", 1);
142
		// }
143
		// catch (Exception ex) {
144
		// ex.printStackTrace();
145
		// }
146
		// }
147
		videoComposite = new Composite(this, SWT.EMBEDDED | SWT.NO_BACKGROUND);
148
		GridData gdata = new GridData(SWT.FILL, SWT.FILL, true, true);
149
		gdata.horizontalSpan = 11;
150
		videoComposite.setLayoutData(gdata);
151
		
152
		factory = new SwtMediaPlayerFactory();
153
		playerCanvas = factory.swt().newCompositeVideoSurface(videoComposite);
154
		
155
		EmbeddedMediaPlayerComponent e = new EmbeddedMediaPlayerComponent();
156
		vlcPlayer = e.mediaPlayer();
157
		vlcPlayer.videoSurface().set(playerCanvas);
158
		
159
		videoComposite.addDisposeListener(new DisposeListener() {
160
			
161
			@Override
162
			public void widgetDisposed(DisposeEvent e) {
163
				// vlcPlayer.submit(new Runnable() {
164
				//
165
				// @Override
166
				// public void run() {
167
				// // vlcPlayer.controls().stop();
168
				// }
169
				// });
170
				vlcPlayer.controls().stop();
171
				vlcPlayer.release();
172
				factory.release();
173
			}
174
		});
175
		
176
		// THE CONTROL BUTTONS
177
		playButton = new Button(this, SWT.PUSH);
178
		GridData playLayoutData = new GridData(SWT.FILL, SWT.CENTER, false, false);
179
		playButton.setLayoutData(playLayoutData);
180
		playButton.setText(MessagesMP.play);
181
		playButton.addSelectionListener(new SelectionListener() {
182
			
183
			@Override
184
			public void widgetSelected(SelectionEvent e) {
185
				vlcPlayer.submit(new Runnable() {
186
					
187
					@Override
188
					public void run() {
189
						if (currentlyPlayed.length() == 0) {
190
							selectMedia();
191
							playButton.setText(MessagesMP.pause);
192
						}
193
						else if (vlcPlayer.status().isPlaying()) {
194
							vlcPlayer.controls().pause();
195
							playButton.setText(MessagesMP.resume);
196
						}
197
						else if (hasEnded) {
198
							replay();
199
						}
200
						else {
201
							vlcPlayer.controls().play();
202
							playButton.setText(MessagesMP.pause);
203
						}
204
					}
205
				});
206
			}
207
			
208
			@Override
209
			public void widgetDefaultSelected(SelectionEvent e) {}
210
		});
211
		
212
		// Button browseButton = new Button(this,SWT.PUSH);
213
		// browseButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
214
		// browseButton.setText("Open...");
215
		// browseButton.addSelectionListener(new SelectionListener() {
216
		// @Override
217
		// public void widgetSelected(SelectionEvent e) {
218
		// selectMedia();
219
		// }
220
		//
221
		// @Override
222
		// public void widgetDefaultSelected(SelectionEvent e) {}
223
		// });
224
		
225
		stopButton = new Button(this, SWT.PUSH);
226
		stopButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
227
		stopButton.setText(MessagesMP.stop);
228
		stopButton.addSelectionListener(new SelectionListener() {
229
			
230
			@Override
231
			public void widgetSelected(SelectionEvent e) {
232
				stop();
233
			}
234
			
235
			@Override
236
			public void widgetDefaultSelected(SelectionEvent e) {}
237
		});
238
		
239
		timeLabel = new Label(this, SWT.NONE);
240
		timeLabel.setText("00:00"); //$NON-NLS-1$
241
		
242
		timeRange = new TripleRangeSlider(this, SWT.None);
243
		timeRange.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
244
		timeRange.setToolTipText(MessagesMP.time_range);
245
		timeRange.addSelectionListener(new SelectionListener() {
246
			
247
			@Override
248
			public void widgetSelected(SelectionEvent e) {
249
				TripleRangeSlider.SELECTED_KNOB sk = timeRange.getLastSelectedKnob();
250
				switch (sk) {
251
					case UPPER:
252
						end = timeRange.getUpperValue();
253
						
254
						if (end < time) {
255
							// System.out.println("Upper changed: fix time");
256
							time = end;
257
							vlcPlayer.controls().setTime(time);
258
						}
259
						break;
260
					case LOWER:
261
						start = timeRange.getLowerValue();
262
						if (start > time) {
263
							// System.out.println("Lower changed: fix time");
264
							time = start;
265
							vlcPlayer.controls().setTime(time);
266
						}
267
						break;
268
					case MIDDLE:
269
						
270
						time = timeRange.getMiddleValue();
271
						// System.out.println("Middle changed: fix time: "+time);
272
						vlcPlayer.controls().setTime(time);
273
						break;
274
					default:
275
						// nothing
276
				}
277
				// System.out.println("time range: "+start+" -> "+end+" time="+time);
278
			}
279
			
280
			@Override
281
			public void widgetDefaultSelected(SelectionEvent e) {}
282
		});
283
		
284
		repeatButton = new Button(this, SWT.CHECK);
285
		repeatButton.setText(MessagesMP.repeat);
286
		repeat = BackToMediaPreferences.getInstance().getBoolean(BackToMediaPreferences.REPEAT);
287
		repeatButton.setSelection(repeat);
288
		repeatButton.addSelectionListener(new SelectionListener() {
289
			
290
			@Override
291
			public void widgetSelected(SelectionEvent e) {
292
				repeat = repeatButton.getSelection();
293
			}
294
			
295
			@Override
296
			public void widgetDefaultSelected(SelectionEvent e) {}
297
		});
298
		
299
		Label l = new Label(this, SWT.NONE);
300
		l.setText(MessagesMP.rate);
301
		
302
		rateField = new Scale(this, SWT.BORDER);
303
		GridData gdata4 = new GridData(SWT.FILL, SWT.CENTER, false, false);
304
		gdata4.widthHint = 100;
305
		rateField.setLayoutData(gdata4);
306
		rateField.setMaximum(140);
307
		rateField.setMinimum(70);
308
		rateField.setSelection(100);
309
		rateField.setPageIncrement(5);
310
		
311
		rateField.addSelectionListener(new SelectionListener() {
312
			
313
			@Override
314
			public void widgetSelected(SelectionEvent e) {
315
				float rate = rateField.getSelection() / 100.0f;
316
				vlcPlayer.controls().setRate(rate);
317
				rateValueLabel.setText("" + rateField.getSelection() + "%");
318
			}
319
			
320
			@Override
321
			public void widgetDefaultSelected(SelectionEvent e) {}
322
		});
323
		
324
		rateValueLabel = new Label(this, SWT.NONE);
325
		rateValueLabel.setText("100%");//$NON-NLS-1$
326
		
327
		l = new Label(this, SWT.NONE);
328
		l.setText(MessagesMP.volume);
329
		
330
		volumeField = new Scale(this, SWT.BORDER);
331
		gdata4 = new GridData(SWT.FILL, SWT.CENTER, false, false);
332
		gdata4.widthHint = 100;
333
		volumeField.setLayoutData(gdata4);
334
		volumeField.setMinimum(0);
335
		volumeField.setMaximum(100);
336
		volumeField.setSelection(volume);
337
		volumeField.setPageIncrement(5);
338
		volumeField.addSelectionListener(new SelectionListener() {
339
			
340
			@Override
341
			public void widgetSelected(SelectionEvent e) {
342
				vlcPlayer.audio().setVolume(volumeField.getSelection());
343
				volume = volumeField.getSelection();
344
				volumeValueLabel.setText("" + volume + "%");
345
			}
346
			
347
			@Override
348
			public void widgetDefaultSelected(SelectionEvent e) {}
349
		});
350
		
351
		volumeValueLabel = new Label(this, SWT.NONE);
352
		volumeValueLabel.setText("100%");
353
		
354
		vlcPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
355
			
356
			@Override
357
			public void opening(MediaPlayer mediaPlayer) {
358
				Log.finer("Opening media...");
359
			}
360
			
361
			@Override
362
			public void finished(MediaPlayer mediaPlayer) {
363
				Log.finer("Finished playing media...");
364
				mediaPlayer.submit(new Runnable() {
365
					
366
					@Override
367
					public void run() {
368
						if (repeat) {
369
							replay();
370
						}
371
						else {
372
							hasEnded = true;
373
						}
374
					}
375
				});
376
			}
377
		});
378
		
379
		vlcPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
380
			
381
			@Override
382
			public void timeChanged(MediaPlayer mediaPlayer, final long arg1) {
383
				
384
				mediaPlayer.submit(new Runnable() {
385
					
386
					@Override
387
					public void run() {
388
						time = arg1;
389
						if (previous == time) {
390
							return;
391
						}
392
						previous = time;
393
						
394
						timeLabel.getDisplay().syncExec(new Runnable() {
395
							
396
							@Override
397
							public void run() {
398
								if (timeRange.isDisposed()) {
399
									return;
400
								}
401
								if (!timeRange.isDragMiddleKnob()) {
402
									timeRange.setMiddleValue((int) time);
403
								}
404
								updateTimeLabel();
405
								
406
								if (arg1 > end && end != start) {
407
									// System.out.println("Time > end :"+arg1 +" > "+end);
408
									if (repeat) {
409
										vlcPlayer.controls().setTime(start);
410
									}
411
									else {
412
										vlcPlayer.controls().stop();
413
									}
414
								}
415
							}
416
						});
417
					}
418
				});
419
			}
420
			
421
			@Override
422
			public void lengthChanged(MediaPlayer mediaPlayer, final long arg1) {
423
				
424
				mediaPlayer.submit(new Runnable() {
425
					
426
					@Override
427
					public void run() {
428
						if (firstLengthEvent) {
429
							firstLengthEvent = false;
430
							
431
							// initialize time range widget limits
432
							timeRange.getDisplay().syncExec(new Runnable() {
433
								
434
								@Override
435
								public void run() {
436
									if (timeRange.isDisposed()) return;
437
									timeRange.setMaximum((int) arg1);
438
									// if (start == end) end = (int)arg1;
439
									
440
									
441
									if (end > 0 && start != end) {
442
										timeRange.setUpperValue(end);
443
									}
444
									else {
445
										timeRange.setUpperValue((int) arg1);
446
									}
447
									
448
									timeRange.setLowerValue(start);
449
									// System.out.println("Range: "+start+" -> "+end+" song length "+arg1);
450
								}
451
							});
452
						}
453
					}
454
				});
455
			}
456
		});
457
	}
458
	
459
	private void updateTimeLabel() {
460
		mins = time / 60000;
461
		secs = (time / 1000) % 60;
462
		timeLabel.setText(String.format("%02d:%02d", mins, secs)); //$NON-NLS-1$
463
		timeLabel.update();
464
	}
465
	
466
	protected void replay() {
467
		if (currentlyPlayed.length() > 0) {
468
			// this.play(currentlyPlayed, startTime, endTime);
469
			vlcPlayer.submit(new Runnable() {
470
				
471
				@Override
472
				public void run() {
473
					vlcPlayer.controls().setTime(start);
474
				}
475
			});
476
			
477
			playButton.setText(MessagesMP.pause);
478
		}
479
	}
480
	
481
	protected void selectMedia() {
482
		Log.fine(MessagesMP.select_file);
483
		
484
		FileDialog fd = new FileDialog(VLCPlayer.this.getShell(), SWT.OPEN);
485
		fd.setText(MessagesMP.select_file_title);
486
		File f = new File(previouslyPlayed);
487
		if (f.isDirectory()) fd.setFilterPath(f.getPath());
488
		else fd.setFilterPath(f.getParent());
489
		
490
		String[] filterExt = { "*.*", "*.mp3", "*.mp4", "*.avi" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
491
		fd.setFilterExtensions(filterExt);
492
		String selected = fd.open();
493
		if (selected == null) {
494
			System.out.println(MessagesMP.cancel);
495
			return;
496
		}
497
		
498
		currentlyPlayed = selected;
499
		previouslyPlayed = selected;
500
		Log.fine(MessagesMP.opening + currentlyPlayed);
501
		play(currentlyPlayed, 0, 0);
502
	}
503
	
504
	/**
505
	 * 
506
	 * @param mrl
507
	 * @param time msec start time
508
	 * @param endtime msec end time
509
	 */
510
	public void play(String mrl, int time, int endtime) {
511
		Log.fine(MessagesMP.bind(MessagesMP.playing, new Object[] { mrl, time, endtime }));
512
		play(mrl, "" + time / 1000.0f, "" + endtime / 1000.0f); //$NON-NLS-1$ //$NON-NLS-2$
513
	}
514
	
515
	public void play(String mrl, int time) {
516
		play(mrl, time, time);
517
	}
518
	
519
	public void hideStopButton() {
520
		if (this.stopButton != null && !this.stopButton.isDisposed()) {
521
			this.stopButton.dispose();
522
		}
523
	}
524
	
525
	DateTimeFormatter hhmmssFormatter = DateTimeFormatter.ISO_LOCAL_TIME;
526
	
527
	/**
528
	 * 
529
	 * @param mrl
530
	 * @param startTime "0.0" or ""hh:mm:ss" format
531
	 * @param endTime "0.0" or ""hh:mm:ss" format
532
	 */
533
	public boolean play(String mrl, String startTime, String endTime) {
534
		
535
		if (startTime.matches("[0-9]+.[0-9]+")) {
536
			start = (int) (1000 * Float.parseFloat(startTime));
537
		}
538
		else if (startTime.matches("[0-9]+:[0-9]+:[0-9]+")) {
539
			if (startTime.indexOf(":") == 1) {
540
				startTime = "0" + startTime;
541
			}
542
			LocalTime time1 = LocalTime.parse(startTime, hhmmssFormatter);
... Ce différentiel a été tronqué car il excède la taille maximale pouvant être affichée.

Formats disponibles : Unified diff