Skip to content

Commit

Permalink
- add subtitle merge feature
Browse files Browse the repository at this point in the history
  • Loading branch information
derreisende77 committed Oct 31, 2024
1 parent 259cebc commit a48ac5b
Show file tree
Hide file tree
Showing 12 changed files with 893 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
- **FEATURE:** Mit der Lucene-Suche können mittels des `duplicate`-Boolean Parameters Filmduplikate berücksichtigt werden.
- **FEATURE:** Via `Ansicht/Übersicht aller Duplikate anzeigen...` werden in einem Dialog per Sender alle vorhandenen Duplikate dargestellt zzgl. der zugeordneten Filme.
- **FEATURE:** Geschwindigkeitsoptimierungen für die moderne Suche.
- **FEATURE:** Mittels Menü `Downloads/Unterttiteldatei zu Video hinzufügen...` kann eine vorhandene Untertiteldatei mit der korrekten Sprachzuordnung zu einem Video hinzugefügt werden. Moderne Videoplayer erkennen die Untertitelspur automatisch und man muss keine separaten Untertiteldateien mehr verwalten.
# **14.1.0**
- JDK 21 wird nun mitgeliefert. Behebt primär Darstellungsfehler von Java Apps unter Windows.
- **macOS/Windows:** ffmpeg 7.0 ist nun enthalten.
Expand Down
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
<controlsfx.version>11.2.1</controlsfx.version>
<flatlaf.version>3.5.2</flatlaf.version>
<guava.version>33.3.0-jre</guava.version>
<icu4j.version>76.1</icu4j.version>
<install4j-maven-plugin.version>1.1.2</install4j-maven-plugin.version>
<jackson.version>2.17.2</jackson.version>
<jaffree.version>2023.09.10</jaffree.version>
Expand Down Expand Up @@ -147,6 +148,12 @@
</properties>

<dependencies>
<dependency>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
<version>${icu4j.version}</version>
</dependency>

<dependency>
<groupId>com.github.lgooddatepicker</groupId>
<artifactId>LGoodDatePicker</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024 derreisende77.
* This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package mediathek.gui.actions;

import mediathek.gui.dialog.subripmerge.MergeSubripVideoDialog;
import mediathek.mainwindow.MediathekGui;

import javax.swing.*;
import java.awt.event.ActionEvent;

public class MergeSubtitleWithVideoAction extends AbstractAction {
private final MediathekGui ui;

public MergeSubtitleWithVideoAction(MediathekGui mediathekGui) {
this.ui = mediathekGui;
putValue(NAME, "Untertiteldatei zu Video hinzufügen...");
}

@Override
public void actionPerformed(ActionEvent e) {
MergeSubripVideoDialog dlg = new MergeSubripVideoDialog(ui);
dlg.setVisible(true);
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
JFDML JFormDesigner: "8.2.4.0.393" Java: "21.0.4" encoding: "UTF-8"

new FormModel {
contentType: "form/swing"
root: new FormRoot {
add( new FormWindow( "javax.swing.JDialog", new FormLayoutManager( class java.awt.BorderLayout ) ) {
name: "this"
"defaultCloseOperation": 2
"modal": true
"title": "Untertitel zu Video hinzufügen"
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
name: "dialogPane"
"border": new javax.swing.border.EmptyBorder( 12, 12, 12, 12 )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class org.jdesktop.layout.GroupLayout ) {
"$horizontalGroup": "par l {seq l {space :::p, par l {seq l {par t:::p {comp label2::::104:x, comp label3::t:p:98:p, comp label1::::104:x}, space :::p, par l {seq l {comp tfVideoFilePath:::::x, space :::p, comp btnSelectInputVideo:::p:33:p}, seq {comp tfSubripFilePath:::::x, space :::p, comp btnSelectInputSubrip:::p:33:p}, seq {comp cbLanguage:::p:155:p, space :0:0:x}}}, seq t {par t {seq {comp label4:::p:104:p, space :6:6:p, comp tfVideoOutputPath:::p:368:p}, seq l {space :p:20:p, comp busyLabel:::p::p}}, space :6:6:p, comp btnSelectVideoOutputPath:::p:33:p}}, space :::p}}"
"$verticalGroup": "par l {seq l {space :::p, par b {comp btnSelectInputSubrip::b:p::p, comp tfSubripFilePath::b:p::p, comp label1::b:p::p}, space :::p, par b {comp label3::b:p::p, comp cbLanguage::b:p::p}, space :::p, par b {comp btnSelectInputVideo::b:p::p, comp label2::b:p::p, comp tfVideoFilePath::b:p::p}, space s:::p, par l {seq l {space :7:7:p, comp label4:::p::p}, comp tfVideoOutputPath:::p::p, comp btnSelectVideoOutputPath:::p::p}, space s:::p, comp busyLabel:::p::p, space :::x}}"
} ) {
name: "contentPanel"
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label1"
"text": "Untertitel-Datei:"
"horizontalAlignment": 4
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "tfSubripFilePath"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "btnSelectInputSubrip"
"text": "..."
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label2"
"text": "Video-Datei:"
"horizontalAlignment": 4
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "tfVideoFilePath"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "btnSelectInputVideo"
"text": "..."
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label3"
"text": "Sprache:"
"horizontalAlignment": 4
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "cbLanguage"
"toolTipText": "Sprache der Untertitel"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label4"
"text": "Zieldatei:"
"horizontalAlignment": 4
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "tfVideoOutputPath"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "btnSelectVideoOutputPath"
"text": "..."
} )
add( new FormComponent( "org.jdesktop.swingx.JXBusyLabel" ) {
name: "busyLabel"
"text": "Führe Video und Untertitel zusammen"
} )
}, new FormLayoutConstraints( class java.lang.String ) {
"value": "Center"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.GridBagLayout ) {
"$columnSpecs": "0:1.0, 0, 80"
"$rowSpecs": "0"
"$hGap": 5
"$vGap": 5
} ) {
name: "buttonBar"
"border": new javax.swing.border.EmptyBorder( 12, 0, 0, 0 )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
add( new FormComponent( "javax.swing.JButton" ) {
name: "btnCancel"
"text": "Abbrechen"
}, new FormLayoutConstraints( class com.jformdesigner.runtime.GridBagConstraintsEx ) {
"gridx": 1
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "btnClose"
"text": "Zusammenführen"
auxiliary() {
"JavaCodeGenerator.variableName": "btnMerge"
}
}, new FormLayoutConstraints( class com.jformdesigner.runtime.GridBagConstraintsEx ) {
"gridy": 0
"gridx": 2
} )
}, new FormLayoutConstraints( class java.lang.String ) {
"value": "South"
} )
}, new FormLayoutConstraints( class java.lang.String ) {
"value": "Center"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 555, 295 )
} )
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public class GuiDownloads extends AGuiTabPanel {
protected DeleteDownloadAction deleteDownloadAction = new DeleteDownloadAction(this);
protected OpenTargetFolderAction openTargetFolderAction = new OpenTargetFolderAction(this);
protected ToggleFilterPanelAction toggleFilterPanelAction = new ToggleFilterPanelAction();
protected MergeSubtitleWithVideoAction mergeSubtitleWithVideoAction = new MergeSubtitleWithVideoAction(MediathekGui.ui());
protected JToolBar swingToolBar = new JToolBar();
private boolean onlyAbos;
private boolean onlyDownloads;
Expand Down Expand Up @@ -341,6 +342,8 @@ public void installMenuEntries(JMenu menu) {
menu.add(deleteDownloadsAction);
menu.add(editDownloadAction);
menu.addSeparator();
menu.add(mergeSubtitleWithVideoAction);
menu.addSeparator();
menu.add(cbShowDownloadDescription);
menu.addSeparator();
menu.add(miMarkFilmAsSeen);
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/mediathek/tool/ColorUtils.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
/*
* Copyright (c) 2024 derreisende77.
* This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package mediathek.tool;

import java.awt.*;
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/mediathek/tool/DarkModeDetector.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
/*
* Copyright (c) 2024 derreisende77.
* This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package mediathek.tool;

import org.apache.commons.lang3.SystemUtils;
Expand Down
68 changes: 68 additions & 0 deletions src/main/java/mediathek/tool/FileDialogs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import org.apache.commons.lang3.SystemUtils
import java.awt.FileDialog
import java.awt.Frame
import java.io.File
import javax.swing.JDialog
import javax.swing.JFileChooser

class FileDialogs {
Expand Down Expand Up @@ -44,6 +45,40 @@ class FileDialogs {
return resultFile
}

@JvmStatic
fun chooseLoadFileLocation(parent: JDialog, title: String, initialFile: String): File? {
var resultFile: File? = null

if (SystemUtils.IS_OS_MAC_OSX || SystemUtils.IS_OS_WINDOWS) {
val chooser = FileDialog(parent, title)
chooser.mode = FileDialog.LOAD
chooser.isMultipleMode = false
if (initialFile.isNotEmpty()) {
chooser.directory = initialFile
}
chooser.isVisible = true
if (chooser.file != null) {
val files = chooser.files
if (files.isNotEmpty()) {
resultFile = files[0]
}
}
} else {
val chooser = JFileChooser()
if (initialFile.isNotEmpty()) {
chooser.currentDirectory = File(initialFile)
}
chooser.fileSelectionMode = JFileChooser.FILES_ONLY
chooser.dialogTitle = title
chooser.isFileHidingEnabled = true
if (chooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) {
resultFile = File(chooser.selectedFile.absolutePath)
}
}

return resultFile
}

@JvmStatic
fun chooseLoadFileLocation(parent: Frame, title: String, initialFile: String): File? {
var resultFile: File? = null
Expand Down Expand Up @@ -117,5 +152,38 @@ class FileDialogs {
}
return resultFile
}

@JvmStatic
fun chooseSaveFileLocation(parent: JDialog, title: String, initialFile: String): File? {
var resultFile: File? = null
if (SystemUtils.IS_OS_MAC_OSX || SystemUtils.IS_OS_WINDOWS) {
val chooser = FileDialog(parent, title)
chooser.mode = FileDialog.SAVE
chooser.isMultipleMode = false
if (initialFile.isNotEmpty()) {
chooser.directory = initialFile
}
chooser.isVisible = true
if (chooser.file != null) {
val files = chooser.files
if (files.isNotEmpty()) {
resultFile = files[0]
}
}
} else {
//Linux HiDPI does not work with either AWT FileDialog or JavaFX FileChooser as of JFX 14.0.1
val chooser = JFileChooser()
if (initialFile.isNotEmpty()) {
chooser.currentDirectory = File(initialFile)
}
chooser.fileSelectionMode = JFileChooser.FILES_ONLY
chooser.dialogTitle = title
chooser.isFileHidingEnabled = true
if (chooser.showSaveDialog(parent) == JFileChooser.APPROVE_OPTION) {
resultFile = File(chooser.selectedFile.absolutePath)
}
}
return resultFile
}
}
}
Loading

0 comments on commit a48ac5b

Please sign in to comment.