feat(convert): add PDF to Video converter (FFmpeg) with MP4/WebM support (#4704)

# Description of Changes

This pull request introduces support for FFmpeg as a new external tool
in the application. It adds configuration options for FFmpeg session
limits and timeouts, updates the process execution and tool-checking
utilities to handle FFmpeg, and expands endpoint configuration to
include FFmpeg-dependent features. Corresponding unit tests have also
been added to ensure FFmpeg detection works as expected.

**FFmpeg Integration and Configuration:**

* Added FFmpeg session limit and timeout configuration options to
`ApplicationProperties`, with default values and getter methods.
[[1]](diffhunk://#diff-1c357db0a3e88cf5bedd4a5852415fadad83b8b3b9eb56e67059d8b9d8b10702R631)
[[2]](diffhunk://#diff-1c357db0a3e88cf5bedd4a5852415fadad83b8b3b9eb56e67059d8b9d8b10702R672-R675)
[[3]](diffhunk://#diff-1c357db0a3e88cf5bedd4a5852415fadad83b8b3b9eb56e67059d8b9d8b10702R702)
[[4]](diffhunk://#diff-1c357db0a3e88cf5bedd4a5852415fadad83b8b3b9eb56e67059d8b9d8b10702R743-R746)
* Updated `ProcessExecutor` to recognize FFmpeg as a process type, and
to use the new session limit and timeout configuration for FFmpeg
processes.
[[1]](diffhunk://#diff-8424a11112fff55cc28467c4d531e451a485911ed1aeb0aea772c9fa7dc3aa6aL305-R316)
[[2]](diffhunk://#diff-8424a11112fff55cc28467c4d531e451a485911ed1aeb0aea772c9fa7dc3aa6aR74-R78)
[[3]](diffhunk://#diff-8424a11112fff55cc28467c4d531e451a485911ed1aeb0aea772c9fa7dc3aa6aR133-R137)

**Tool Detection and Exception Handling:**

* Implemented `isFfmpegAvailable()` in `CheckProgramInstall` to detect
FFmpeg installation, with caching for efficiency.
[[1]](diffhunk://#diff-7b61807107c689e3824a5f8fd42c27ab072a67a5666f24445bd6895937351690R14)
[[2]](diffhunk://#diff-7b61807107c689e3824a5f8fd42c27ab072a67a5666f24445bd6895937351690R60-R78)
* Added a specific exception factory method for missing FFmpeg in
`ExceptionUtils`.

**Endpoint Configuration:**

* Registered the new `pdf-to-video` endpoint under the "Convert",
"Java", and "FFmpeg" groups, and updated the tool group logic to include
"FFmpeg".
[[1]](diffhunk://#diff-3cddb66d1cf93eeb8103ccd17cee8ed006e0c0ee006d0ee1cf42d512f177e437R265)
[[2]](diffhunk://#diff-3cddb66d1cf93eeb8103ccd17cee8ed006e0c0ee006d0ee1cf42d512f177e437R395)
[[3]](diffhunk://#diff-3cddb66d1cf93eeb8103ccd17cee8ed006e0c0ee006d0ee1cf42d512f177e437R452-R454)
[[4]](diffhunk://#diff-3cddb66d1cf93eeb8103ccd17cee8ed006e0c0ee006d0ee1cf42d512f177e437L496-R502)

**Testing Enhancements:**

* Added and updated unit tests in `CheckProgramInstallTest` to verify
FFmpeg detection, including scenarios for installed, not installed, and
caching behavior.
[[1]](diffhunk://#diff-0eaf917d935710f0f5e18f12db600be47b8439d628d65a97a3db34133231790eR29)
[[2]](diffhunk://#diff-0eaf917d935710f0f5e18f12db600be47b8439d628d65a97a3db34133231790eR38-R45)
[[3]](diffhunk://#diff-0eaf917d935710f0f5e18f12db600be47b8439d628d65a97a3db34133231790eR67-R75)
[[4]](diffhunk://#diff-0eaf917d935710f0f5e18f12db600be47b8439d628d65a97a3db34133231790eR222-R262)

---

## Checklist

### General

- [x] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [x] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [x] I have performed a self-review of my own code
- [x] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
This commit is contained in:
Ludy 2025-10-30 23:54:33 +01:00 committed by GitHub
parent 43e0d73338
commit 7f7d6fd1c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
60 changed files with 1301 additions and 25 deletions

View File

@ -1,6 +1,6 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.7
rev: v0.14.2
hooks:
- id: ruff
args:
@ -26,7 +26,7 @@ repos:
hooks:
- id: gitleaks
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
rev: v6.0.0
hooks:
- id: end-of-file-fixer
files: ^.*(\.js|\.java|\.py|\.yml)$

View File

@ -55,6 +55,7 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
openssl \
openssl-dev \
openjdk21-jre \
ffmpeg \
# Doc conversion
gcompat \
libc6-compat \

View File

@ -19,6 +19,7 @@ RUN apt-get update && apt-get install -y \
# settings.yml | tessdataDir: /usr/share/tesseract-ocr/5/tessdata
tesseract-ocr \
tesseract-ocr-eng \
ffmpeg \
fonts-terminus fonts-dejavu fonts-font-awesome fonts-noto fonts-noto-core fonts-noto-cjk fonts-noto-extra fonts-liberation fonts-linuxlibertine fonts-urw-base35 \
python3-uno \
python3-venv \

View File

@ -69,6 +69,7 @@ RUN echo "@main https://dl-cdn.alpinelinux.org/alpine/edge/main" | tee -a /etc/a
openssl \
openssl-dev \
openjdk21-jre \
ffmpeg \
# Doc conversion
gcompat \
libc6-compat \

View File

@ -647,6 +647,7 @@ public class ApplicationProperties {
private int tesseractSessionLimit;
private int ghostscriptSessionLimit;
private int ocrMyPdfSessionLimit;
private int ffmpegSessionLimit;
public int getQpdfSessionLimit() {
return qpdfSessionLimit > 0 ? qpdfSessionLimit : 2;
@ -687,6 +688,10 @@ public class ApplicationProperties {
public int getOcrMyPdfSessionLimit() {
return ocrMyPdfSessionLimit > 0 ? ocrMyPdfSessionLimit : 2;
}
public int getFfmpegSessionLimit() {
return ffmpegSessionLimit > 0 ? ffmpegSessionLimit : 2;
}
}
@Data
@ -713,6 +718,7 @@ public class ApplicationProperties {
private long qpdfTimeoutMinutes;
private long ghostscriptTimeoutMinutes;
private long ocrMyPdfTimeoutMinutes;
private long ffmpegTimeoutMinutes;
public long getTesseractTimeoutMinutes() {
return tesseractTimeoutMinutes > 0 ? tesseractTimeoutMinutes : 30;
@ -753,6 +759,10 @@ public class ApplicationProperties {
public long getOcrMyPdfTimeoutMinutes() {
return ocrMyPdfTimeoutMinutes > 0 ? ocrMyPdfTimeoutMinutes : 30;
}
public long getFfmpegTimeoutMinutes() {
return ffmpegTimeoutMinutes > 0 ? ffmpegTimeoutMinutes : 30;
}
}
}
}

View File

@ -11,6 +11,8 @@ public class CheckProgramInstall {
private static final List<String> PYTHON_COMMANDS = Arrays.asList("python3", "python");
private static boolean pythonAvailableChecked = false;
private static String availablePythonCommand = null;
private static boolean ffmpegAvailableChecked = false;
private static boolean ffmpegAvailable = false;
/**
* Checks which Python command is available and returns it.
@ -56,4 +58,25 @@ public class CheckProgramInstall {
public static boolean isPythonAvailable() {
return getAvailablePythonCommand() != null;
}
/**
* Checks if FFmpeg is available on the system.
*
* @return true if FFmpeg is installed and accessible, false otherwise.
*/
public static boolean isFfmpegAvailable() {
if (!ffmpegAvailableChecked) {
try {
ProcessExecutorResult result =
ProcessExecutor.getInstance(ProcessExecutor.Processes.FFMPEG)
.runCommandWithOutputHandling(Arrays.asList("ffmpeg", "-version"));
ffmpegAvailable = true;
} catch (IOException | InterruptedException e) {
ffmpegAvailable = false;
} finally {
ffmpegAvailableChecked = true;
}
}
return ffmpegAvailable;
}
}

View File

@ -34,11 +34,14 @@ public class ExceptionUtils {
if (context != null && !context.isEmpty()) {
message =
String.format(
"Error %s: PDF file appears to be corrupted or damaged. Please try using the 'Repair PDF' feature first to fix the file before proceeding with this operation.",
"Error %s: PDF file appears to be corrupted or damaged. Please try"
+ " using the 'Repair PDF' feature first to fix the file before"
+ " proceeding with this operation.",
context);
} else {
message =
"PDF file appears to be corrupted or damaged. Please try using the 'Repair PDF' feature first to fix the file before proceeding with this operation.";
"PDF file appears to be corrupted or damaged. Please try using the 'Repair PDF'"
+ " feature first to fix the file before proceeding with this operation.";
}
return new IOException(message, cause);
}
@ -51,7 +54,8 @@ public class ExceptionUtils {
*/
public static IOException createMultiplePdfCorruptedException(Exception cause) {
String message =
"One or more PDF files appear to be corrupted or damaged. Please try using the 'Repair PDF' feature on each file first before attempting to merge them.";
"One or more PDF files appear to be corrupted or damaged. Please try using the"
+ " 'Repair PDF' feature on each file first before attempting to merge them.";
return new IOException(message, cause);
}
@ -63,7 +67,10 @@ public class ExceptionUtils {
*/
public static IOException createPdfEncryptionException(Exception cause) {
String message =
"The PDF appears to have corrupted encryption data. This can happen when the PDF was created with incompatible encryption methods. Please try using the 'Repair PDF' feature first, or contact the document creator for a new copy.";
"The PDF appears to have corrupted encryption data. This can happen when the PDF"
+ " was created with incompatible encryption methods. Please try using the"
+ " 'Repair PDF' feature first, or contact the document creator for a new"
+ " copy.";
return new IOException(message, cause);
}
@ -75,7 +82,8 @@ public class ExceptionUtils {
*/
public static IOException createPdfPasswordException(Exception cause) {
String message =
"The PDF Document is passworded and either the password was not provided or was incorrect";
"The PDF Document is passworded and either the password was not provided or was"
+ " incorrect";
return new IOException(message, cause);
}
@ -180,6 +188,15 @@ public class ExceptionUtils {
"error.toolRequired", "{0} is required for {1}", null, "Python", "WebP conversion");
}
public static IOException createFfmpegRequiredException() {
return createIOException(
"error.toolRequired",
"{0} is required for {1}",
null,
"FFmpeg",
"PDF to Video Slideshow conversion");
}
/** Create file operation exceptions. */
public static IOException createFileNotFoundException(String fileId) {
return createIOException("error.fileNotFound", "File not found with ID: {0}", null, fileId);
@ -345,9 +362,11 @@ public class ExceptionUtils {
int pageNumber, int dpi, Throwable cause) {
String message =
MessageFormat.format(
"Out of memory or image-too-large error while rendering PDF page {0} at {1} DPI. "
+ "This can occur when the resulting image exceeds Java's array/memory limits (e.g., NegativeArraySizeException). "
+ "Please use a lower DPI value (recommended: 150 or less) or process the document in smaller chunks.",
"Out of memory or image-too-large error while rendering PDF page {0} at {1}"
+ " DPI. This can occur when the resulting image exceeds Java's"
+ " array/memory limits (e.g., NegativeArraySizeException). Please use"
+ " a lower DPI value (recommended: 150 or less) or process the"
+ " document in smaller chunks.",
pageNumber, dpi);
return new RuntimeException(message, cause);
}
@ -378,9 +397,11 @@ public class ExceptionUtils {
public static RuntimeException createOutOfMemoryDpiException(int dpi, Throwable cause) {
String message =
MessageFormat.format(
"Out of memory or image-too-large error while rendering PDF at {0} DPI. "
+ "This can occur when the resulting image exceeds Java's array/memory limits (e.g., NegativeArraySizeException). "
+ "Please use a lower DPI value (recommended: 150 or less) or process the document in smaller chunks.",
"Out of memory or image-too-large error while rendering PDF at {0} DPI."
+ " This can occur when the resulting image exceeds Java's array/memory"
+ " limits (e.g., NegativeArraySizeException). Please use a lower DPI"
+ " value (recommended: 150 or less) or process the document in smaller"
+ " chunks.",
dpi);
return new RuntimeException(message, cause);
}

View File

@ -71,6 +71,11 @@ public class ProcessExecutor {
.getProcessExecutor()
.getSessionLimit()
.getInstallAppSessionLimit();
case FFMPEG ->
applicationProperties
.getProcessExecutor()
.getSessionLimit()
.getFfmpegSessionLimit();
case TESSERACT ->
applicationProperties
.getProcessExecutor()
@ -125,6 +130,11 @@ public class ProcessExecutor {
.getProcessExecutor()
.getTimeoutMinutes()
.getInstallAppTimeoutMinutes();
case FFMPEG ->
applicationProperties
.getProcessExecutor()
.getTimeoutMinutes()
.getFfmpegTimeoutMinutes();
case TESSERACT ->
applicationProperties
.getProcessExecutor()
@ -302,7 +312,8 @@ public class ProcessExecutor {
TESSERACT,
QPDF,
GHOSTSCRIPT,
OCR_MY_PDF
OCR_MY_PDF,
FFMPEG
}
@Setter

View File

@ -2,6 +2,7 @@ package stirling.software.common.model;
import static org.junit.jupiter.api.Assertions.*;
import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
@ -45,11 +46,15 @@ class ApplicationPropertiesLogicTest {
String expectedLibre = Paths.get(expectedBase, "libreoffice").toString();
assertEquals(expectedLibre, tfm.getLibreofficeDir());
tfm.setBaseTmpDir("/custom/base");
assertEquals("/custom/base", normalize.apply(tfm.getBaseTmpDir()));
tfm.setBaseTmpDir(File.separator + "custom" + File.separator + "base");
assertEquals(
File.separator + "custom" + File.separator + "base",
normalize.apply(tfm.getBaseTmpDir()));
tfm.setLibreofficeDir("/opt/libre");
assertEquals("/opt/libre", normalize.apply(tfm.getLibreofficeDir()));
tfm.setLibreofficeDir(File.separator + "opt" + File.separator + "libre");
assertEquals(
File.separator + "opt" + File.separator + "libre",
normalize.apply(tfm.getLibreofficeDir()));
}
@Test
@ -240,12 +245,13 @@ class ApplicationPropertiesLogicTest {
void collection_isValid_true_when_non_empty_even_if_element_is_blank() {
ApplicationProperties.Security.OAUTH2 oauth2 = new ApplicationProperties.Security.OAUTH2();
// Aktuelles Verhalten: prüft NUR !isEmpty(), nicht Inhalt
// Current behavior: checks ONLY !isEmpty(), not the content
Collection<String> oneBlank = new ArrayList<>();
oneBlank.add(" ");
assertTrue(
oauth2.isValid(oneBlank, "scopes"),
"Dokumentiert aktuelles Verhalten: nicht-leere Liste gilt als gültig, auch wenn Element leer/blank ist");
"Documents current behavior: non-empty list is considered valid, even if an element"
+ " is empty/blank");
}
}

View File

@ -26,6 +26,7 @@ class CheckProgramInstallTest {
private MockedStatic<ProcessExecutor> mockProcessExecutor;
private ProcessExecutor mockExecutor;
private ProcessExecutor mockFfmpegExecutor;
@BeforeEach
void setUp() throws Exception {
@ -34,10 +35,14 @@ class CheckProgramInstallTest {
// Set up mock for ProcessExecutor
mockExecutor = Mockito.mock(ProcessExecutor.class);
mockFfmpegExecutor = Mockito.mock(ProcessExecutor.class);
mockProcessExecutor = mockStatic(ProcessExecutor.class);
mockProcessExecutor
.when(() -> ProcessExecutor.getInstance(ProcessExecutor.Processes.PYTHON_OPENCV))
.thenReturn(mockExecutor);
mockProcessExecutor
.when(() -> ProcessExecutor.getInstance(ProcessExecutor.Processes.FFMPEG))
.thenReturn(mockFfmpegExecutor);
}
@AfterEach
@ -59,6 +64,15 @@ class CheckProgramInstallTest {
CheckProgramInstall.class.getDeclaredField("availablePythonCommand");
availablePythonCommandField.setAccessible(true);
availablePythonCommandField.set(null, null);
Field ffmpegAvailableCheckedField =
CheckProgramInstall.class.getDeclaredField("ffmpegAvailableChecked");
ffmpegAvailableCheckedField.setAccessible(true);
ffmpegAvailableCheckedField.set(null, false);
Field ffmpegAvailableField = CheckProgramInstall.class.getDeclaredField("ffmpegAvailable");
ffmpegAvailableField.setAccessible(true);
ffmpegAvailableField.set(null, false);
}
@Test
@ -204,4 +218,45 @@ class CheckProgramInstallTest {
// Verify getAvailablePythonCommand was called internally
verify(mockExecutor).runCommandWithOutputHandling(Arrays.asList("python3", "--version"));
}
@Test
void testIsFfmpegAvailable_WhenInstalled() throws Exception {
resetStaticFields();
ProcessExecutorResult result = Mockito.mock(ProcessExecutorResult.class);
when(mockFfmpegExecutor.runCommandWithOutputHandling(Arrays.asList("ffmpeg", "-version")))
.thenReturn(result);
assertTrue(CheckProgramInstall.isFfmpegAvailable());
verify(mockFfmpegExecutor)
.runCommandWithOutputHandling(Arrays.asList("ffmpeg", "-version"));
}
@Test
void testIsFfmpegAvailable_WhenNotInstalled() throws Exception {
resetStaticFields();
when(mockFfmpegExecutor.runCommandWithOutputHandling(Arrays.asList("ffmpeg", "-version")))
.thenThrow(new IOException("Command not found"));
assertFalse(CheckProgramInstall.isFfmpegAvailable());
verify(mockFfmpegExecutor)
.runCommandWithOutputHandling(Arrays.asList("ffmpeg", "-version"));
}
@Test
void testIsFfmpegAvailable_CachesResult() throws Exception {
resetStaticFields();
ProcessExecutorResult result = Mockito.mock(ProcessExecutorResult.class);
when(mockFfmpegExecutor.runCommandWithOutputHandling(Arrays.asList("ffmpeg", "-version")))
.thenReturn(result);
assertTrue(CheckProgramInstall.isFfmpegAvailable());
when(mockFfmpegExecutor.runCommandWithOutputHandling(Arrays.asList("ffmpeg", "-version")))
.thenThrow(new IOException("Command not found"));
assertTrue(CheckProgramInstall.isFfmpegAvailable());
verify(mockFfmpegExecutor, times(1))
.runCommandWithOutputHandling(Arrays.asList("ffmpeg", "-version"));
}
}

View File

@ -262,6 +262,7 @@ public class EndpointConfiguration {
addEndpointToGroup("Convert", "eml-to-pdf");
addEndpointToGroup("Convert", "pdf-to-vector");
addEndpointToGroup("Convert", "vector-to-pdf");
addEndpointToGroup("Convert", "pdf-to-video");
// Adding endpoints to "Security" group
addEndpointToGroup("Security", "add-password");
@ -391,6 +392,7 @@ public class EndpointConfiguration {
addEndpointToGroup("Java", "add-attachments");
addEndpointToGroup("Java", "compress-pdf");
addEndpointToGroup("rar", "pdf-to-cbr");
addEndpointToGroup("Java", "pdf-to-video");
// Javascript
addEndpointToGroup("Javascript", "pdf-organizer");
@ -447,6 +449,9 @@ public class EndpointConfiguration {
// Pdftohtml dependent endpoints
addEndpointToGroup("Pdftohtml", "pdf-to-html");
addEndpointToGroup("Pdftohtml", "pdf-to-markdown");
// FFmpeg dependent endpoints
addEndpointToGroup("FFmpeg", "pdf-to-video");
}
private void processEnvironmentConfigs() {
@ -493,7 +498,8 @@ public class EndpointConfiguration {
|| "Javascript".equals(group)
|| "Weasyprint".equals(group)
|| "Pdftohtml".equals(group)
|| "rar".equals(group);
|| "rar".equals(group)
|| "FFmpeg".equals(group);
}
private boolean isEndpointEnabledDirectly(String endpoint) {

View File

@ -67,6 +67,7 @@ public class ExternalAppDepConfig {
tmp.put("qpdf", List.of("qpdf"));
tmp.put("tesseract", List.of("tesseract"));
tmp.put("rar", List.of("rar"));
tmp.put("ffmpeg", List.of("FFmpeg"));
this.commandToGroupMapping = Collections.unmodifiableMap(tmp);
}

View File

@ -0,0 +1,281 @@
package stirling.software.SPDF.controller.api.converters;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.github.pixee.security.Filenames;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import stirling.software.SPDF.model.api.converters.PdfToVideoRequest;
import stirling.software.common.model.ApplicationProperties;
import stirling.software.common.service.CustomPDFDocumentFactory;
import stirling.software.common.util.ApplicationContextProvider;
import stirling.software.common.util.CheckProgramInstall;
import stirling.software.common.util.ExceptionUtils;
import stirling.software.common.util.ProcessExecutor;
import stirling.software.common.util.ProcessExecutor.ProcessExecutorResult;
import stirling.software.common.util.TempDirectory;
import stirling.software.common.util.TempFile;
import stirling.software.common.util.TempFileManager;
import stirling.software.common.util.WebResponseUtils;
@RestController
@RequestMapping("/api/v1/convert")
@Tag(name = "Convert", description = "Convert APIs")
@RequiredArgsConstructor
public class ConvertPdfToVideoController {
private static final Set<String> SUPPORTED_FORMATS = Set.of("mp4", "webm");
private static final Map<String, String> RESOLUTION_FILTERS =
Map.of(
"ORIGINAL", "scale=trunc(iw/2)*2:trunc(ih/2)*2,setsar=1",
"1080P", "scale=-2:1080,setsar=1",
"720P", "scale=-2:720,setsar=1",
"480P", "scale=-2:480,setsar=1");
private final CustomPDFDocumentFactory pdfDocumentFactory;
private final TempFileManager tempFileManager;
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE, value = "/pdf/video")
@Operation(
summary = "Convert PDF to Video Slideshow",
description =
"This endpoint converts a PDF document into a slideshow-style video."
+ " Input:PDF Output:Video Type:SISO")
public ResponseEntity<byte[]> convertPdfToVideo(@ModelAttribute PdfToVideoRequest request)
throws Exception {
if (!CheckProgramInstall.isFfmpegAvailable()) {
throw ExceptionUtils.createFfmpegRequiredException();
}
MultipartFile inputFile = request.getFileInput();
if (inputFile == null || inputFile.isEmpty()) {
throw ExceptionUtils.createPdfFileRequiredException();
}
if (!MediaType.APPLICATION_PDF_VALUE.equals(inputFile.getContentType())) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
float opacity = request.getOpacity() != null ? request.getOpacity() : 1.0f;
if (opacity < 0.0f || opacity > 1.0f) {
throw ExceptionUtils.createIllegalArgumentException(
"error.invalidFormat", "Invalid {0} format: {1}", "opacity", opacity);
}
String format = normalizeFormat(request.getVideoFormat());
int secondsPerPage = request.getSecondsPerPage() != null ? request.getSecondsPerPage() : 3;
if (secondsPerPage <= 0) {
throw ExceptionUtils.createIllegalArgumentException(
"error.invalidFormat",
"Invalid {0} format: {1}",
"secondsPerPage",
secondsPerPage);
}
int dpi = request.getDpi() != null ? request.getDpi() : 150;
int maxDpi = getMaxDpi();
if (dpi > maxDpi) {
throw ExceptionUtils.createIllegalArgumentException(
"error.dpiExceedsLimit",
"DPI value {0} exceeds maximum safe limit of {1}.",
dpi,
maxDpi);
}
if (dpi < 72) {
throw ExceptionUtils.createIllegalArgumentException(
"error.invalidFormat", "Invalid {0} format: {1}", "dpi", dpi);
}
String resolution =
request.getResolution() != null
? request.getResolution().toUpperCase(Locale.ROOT)
: "ORIGINAL";
if (!RESOLUTION_FILTERS.containsKey(resolution)) {
resolution = "ORIGINAL";
}
String watermarkText = request.getWatermarkText();
boolean isWatermarkEnabled = watermarkText != null && !watermarkText.isBlank();
String originalPdfFileName = Filenames.toSimpleFileName(inputFile.getOriginalFilename());
if (originalPdfFileName == null || originalPdfFileName.isBlank()) {
originalPdfFileName = "document.pdf";
}
String pdfBaseName =
originalPdfFileName.contains(".")
? originalPdfFileName.substring(0, originalPdfFileName.lastIndexOf('.'))
: originalPdfFileName;
try (TempFile inputTempFile = new TempFile(tempFileManager, ".pdf");
TempDirectory framesDirectory = new TempDirectory(tempFileManager);
TempFile outputVideo = new TempFile(tempFileManager, "." + format)) {
inputFile.transferTo(inputTempFile.getFile());
generateFrames(
inputTempFile.getPath(),
framesDirectory.getPath(),
dpi,
opacity,
watermarkText,
isWatermarkEnabled);
DecimalFormat decimalFormat =
new DecimalFormat("0.######", DecimalFormatSymbols.getInstance(Locale.ROOT));
String frameRate = decimalFormat.format(1.0d / secondsPerPage);
List<String> command = buildFfmpegCommand(format, resolution, frameRate, outputVideo);
ProcessExecutorResult result =
ProcessExecutor.getInstance(ProcessExecutor.Processes.FFMPEG)
.runCommandWithOutputHandling(
command, framesDirectory.getPath().toFile());
byte[] videoBytes = Files.readAllBytes(outputVideo.getPath());
MediaType mediaType = getMediaType(format);
String outputName = pdfBaseName + "-video." + format;
return WebResponseUtils.bytesToWebResponse(videoBytes, outputName, mediaType);
}
}
private void generateFrames(
Path inputPdf,
Path outputDir,
int dpi,
float opacity,
String watermarkText,
boolean isWatermarkEnabled)
throws IOException {
try (PDDocument document = pdfDocumentFactory.load(inputPdf.toFile())) {
PDFRenderer renderer = new PDFRenderer(document);
renderer.setSubsamplingAllowed(true);
int pageCount = document.getNumberOfPages();
if (pageCount == 0) {
throw ExceptionUtils.createIllegalArgumentException(
"error.invalidFormat", "Invalid {0} format: {1}", "PDF", "no pages");
}
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
BufferedImage image = renderer.renderImageWithDPI(pageIndex, dpi, ImageType.RGB);
if (isWatermarkEnabled) {
applyWatermark(image, opacity, watermarkText);
}
Path framePath =
outputDir.resolve(
String.format(Locale.ROOT, "frame_%05d.png", pageIndex + 1));
ImageIO.write(image, "png", framePath.toFile());
}
}
}
private void applyWatermark(BufferedImage image, float opacity, String watermarkText) {
Graphics2D graphics = image.createGraphics();
try {
graphics.setRenderingHint(
java.awt.RenderingHints.KEY_TEXT_ANTIALIASING,
java.awt.RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
int baseDimension = Math.min(image.getWidth(), image.getHeight());
int fontSize = Math.max(32, baseDimension / 5);
Font font = new Font(Font.SANS_SERIF, Font.BOLD, fontSize);
graphics.setFont(font);
FontMetrics metrics = graphics.getFontMetrics(font);
int textWidth = metrics.stringWidth(watermarkText);
int textHeight = metrics.getAscent();
AffineTransform originalTransform = graphics.getTransform();
double angle = Math.atan2(image.getHeight(), image.getWidth());
graphics.translate(image.getWidth() / 2.0, image.getHeight() / 2.0);
graphics.rotate(-angle);
// Draw shadow
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity / 2));
graphics.setColor(Color.BLACK);
graphics.drawString(watermarkText, -textWidth / 2f + 3, textHeight / 2f + 3);
// Draw main text
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
graphics.setColor(Color.WHITE);
graphics.drawString(watermarkText, -textWidth / 2f, textHeight / 2f);
graphics.setTransform(originalTransform);
} finally {
graphics.dispose();
}
}
private List<String> buildFfmpegCommand(
String format, String resolution, String frameRate, TempFile outputVideo) {
List<String> command = new ArrayList<>();
command.add("ffmpeg");
command.add("-y");
command.add("-framerate");
command.add(frameRate);
command.add("-i");
command.add("frame_%05d.png");
command.add("-vf");
command.add(
RESOLUTION_FILTERS.getOrDefault(resolution, RESOLUTION_FILTERS.get("ORIGINAL")));
if ("mp4".equals(format)) {
command.addAll(
List.of("-c:v", "libx264", "-pix_fmt", "yuv420p", "-movflags", "+faststart"));
} else if ("webm".equals(format)) {
command.addAll(List.of("-c:v", "libvpx-vp9", "-b:v", "0", "-crf", "30"));
}
command.add(outputVideo.getAbsolutePath());
return command;
}
private String normalizeFormat(String requestedFormat) {
String format = requestedFormat != null ? requestedFormat.toLowerCase(Locale.ROOT) : "mp4";
if (!SUPPORTED_FORMATS.contains(format)) {
format = "mp4";
}
return format;
}
private int getMaxDpi() {
ApplicationProperties properties =
ApplicationContextProvider.getBean(ApplicationProperties.class);
if (properties != null && properties.getSystem() != null) {
return properties.getSystem().getMaxDPI();
}
return 500;
}
private MediaType getMediaType(String format) {
return switch (format) {
case "webm" -> MediaType.valueOf("video/webm");
default -> MediaType.valueOf("video/mp4");
};
}
}

View File

@ -186,4 +186,18 @@ public class ConverterWebController {
model.addAttribute("currentPage", "eml-to-pdf");
return "convert/eml-to-pdf";
}
@GetMapping("/pdf-to-video")
@Hidden
public String pdfToVideo(Model model) {
ApplicationProperties properties =
ApplicationContextProvider.getBean(ApplicationProperties.class);
if (properties != null && properties.getSystem() != null) {
model.addAttribute("maxDPI", properties.getSystem().getMaxDPI());
} else {
model.addAttribute("maxDPI", 500);
}
model.addAttribute("currentPage", "pdf-to-video");
return "convert/pdf-to-video";
}
}

View File

@ -0,0 +1,53 @@
package stirling.software.SPDF.model.api.converters;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import stirling.software.common.model.api.PDFFile;
@Data
@EqualsAndHashCode(callSuper = true)
public class PdfToVideoRequest extends PDFFile {
@Schema(
description = "The output video format",
allowableValues = {"mp4", "webm"},
defaultValue = "mp4")
private String videoFormat = "mp4";
@Schema(
description = "Seconds each page should appear in the video",
minimum = "1",
maximum = "30",
defaultValue = "3")
private Integer secondsPerPage = 3;
@Schema(
description = "Target video resolution",
allowableValues = {"ORIGINAL", "1080p", "720p", "480p"},
defaultValue = "ORIGINAL")
private String resolution = "ORIGINAL";
@Schema(
description = "DPI to render PDF pages before encoding",
minimum = "72",
maximum = "500",
defaultValue = "150")
private Integer dpi = 150;
@Schema(
description =
"Opacity of the watermark (only applied if a watermark text is specified)",
minimum = "0.0",
maximum = "1.0",
defaultValue = "0.1")
private Float opacity = 0.1f;
@Schema(
description = "Watermark text to overlay on the video",
example = "Stirling Software",
defaultValue = "Stirling Software")
private String watermarkText;
}

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=تحويل PDF إلى صورة
home.pdfToImage.desc=تحويل ملف PDF إلى صورة. (PNG ، JPEG ، GIF)
pdfToImage.tags=تحويل,صورة,jpg,صورة,صورة فوتوغرافية
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=منظم
home.pdfOrganiser.desc=إزالة / إعادة ترتيب الصفحات بأي ترتيب
pdfOrganiser.tags=مزدوج,زوجي,فردي,ترتيب,نقل
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(مثال: 1,2,8 أو 4,7,12-16 أو 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=إضافة كلمة مرور
addPassword.header=إضافة كلمة مرور (تشفير)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF-dən Şəkilə
home.pdfToImage.desc=PDF-i Şəkilə Çevir. (PNG, JPEG, GIF)
pdfToImage.tags=çevirmə,şəkil,jpg,fotoşəkil,foto
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Səhifələri Sırala
home.pdfOrganiser.desc=Səhifələri Sil/Sırasını Dəyiş
pdfOrganiser.tags=duplex,tək,cüt,sırala,yerini dəyiş
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(məsələn, 1,2,8 və ya 4,7,12-16 və ya 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Şifr Əlavə Et
addPassword.header=Şifr Əlavə Et (Şifrləmə)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF към изображение
home.pdfToImage.desc=Преобразуване на PDF към изображение. (PNG, JPEG, GIF)
pdfToImage.tags=преобразуване,img,jpg,изображение,снимка
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Организиране
home.pdfOrganiser.desc=Премахване/пренареждане на страници към произволен ред
pdfOrganiser.tags=дуплекс,четно,нечетно,сортиране,преместване
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Добавяне на парола
addPassword.header=Добавяне на парола (Шифроване)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF ནས་པར་རིས་ལ།
home.pdfToImage.desc=PDF ནས་པར་རིས་ (PNG, JPEG, GIF) ལ་བསྒྱུར་བ།
pdfToImage.tags=བསྒྱུར་བ།,པར་རིས།,jpg,པར།,འདྲ་པར།
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=གོ་སྒྲིག
home.pdfOrganiser.desc=ཤོག་ངོས་རྣམས་གོ་རིམ་གང་རུང་དུ་སུབ་པའམ་བསྐྱར་སྒྲིག་བྱེད་པ།
pdfOrganiser.tags=ཤོག་ངོས་གཉིས་མ།,ཨང་གྲངས་ཟུང་ལྡན།,ཨང་གྲངས་ཡ་གྲངས།,གོ་རིམ་སྒྲིག་པ།,སྤོ་བ།
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(དཔེར་ན། 1,2,8 ཡང་ན་ 4,7,12-16
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=གསང་ཚིག་སྣོན་པ།
addPassword.header=གསང་ཚིག་སྣོན་པ། (གསང་སྡོམ།)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF a Imatge
home.pdfToImage.desc=Converteix PDF a imatge (PNG, JPEG, GIF)
pdfToImage.tags=conversió,img,jpg,imatge,foto
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organitza
home.pdfOrganiser.desc=Elimina/reorganitza pàgines en qualsevol ordre
pdfOrganiser.tags=duplex,parells,senars,ordenar,moure
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(p. ex. 1,2,8 o 4,7,12-16 o 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Afegir Contrasenya
addPassword.header=Afegir contrasenya (Encriptat)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF na obrázek
home.pdfToImage.desc=Převést PDF na obrázek. (PNG, JPEG, GIF)
pdfToImage.tags=převod,img,jpg,obrázek,fotka
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Uspořádat
home.pdfOrganiser.desc=Odstranit/přeuspořádat stránky v libovolném pořadí
pdfOrganiser.tags=duplex,sudý,lichý,seřadit,přesunout
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(např. 1,2,8 nebo 4,7,12-16 nebo 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Přidat heslo
addPassword.header=Přidat heslo (Zašifrovat)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF til Billede
home.pdfToImage.desc=Konvertér en PDF til et billede. (PNG, JPEG, GIF)
pdfToImage.tags=konvertering,img,jpg,billede,foto
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organisér
home.pdfOrganiser.desc=Fjern/Omarrangér sider i vilkårlig rækkefølge
pdfOrganiser.tags=duplex,lige,ulige,sortér,flyt
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(f.eks. 1,2,8 eller 4,7,12-16 eller 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Tilføj Adgangskode
addPassword.header=Tilføj adgangskode (Kryptér)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF zu Bild
home.pdfToImage.desc=Konvertieren Sie ein PDF in ein Bild (PNG, JPEG, GIF)
pdfToImage.tags=konvertierung,img,jpg,bild,foto
home.PDFToVideo.title=PDF zu Video Slideshow
home.PDFToVideo.desc=Konvertieren Sie ein PDF in ein Slideshow-Video.
PDFToVideo.tags=konvertierung,video,slideshow,presentation
home.pdfOrganiser.title=Organisieren
home.pdfOrganiser.desc=Seiten entfernen und Seitenreihenfolge ändern
pdfOrganiser.tags=duplex,gerade,ungerade,sortieren,verschieben
@ -1260,8 +1264,8 @@ repair.submit=Reparieren
flatten.title=Abflachen
flatten.header=PDFs reduzieren
flatten.flattenOnlyForms=Nur Formulare abflachen
flatten.renderDpi=Rendering DPI (optional, recommended 150 DPI):
flatten.renderDpi.help=Leave blank to use the system default. Higher DPI sharpens output but increases processing time and file size.
flatten.renderDpi=Rendering-DPI (optional, empfohlen 150 DPI):
flatten.renderDpi.help=Leer lassen, um den Systemstandard zu verwenden. Höhere DPI verbessern die Schärfe der Ausgabe, erhöhen jedoch die Verarbeitungszeit und Dateigröße.
flatten.submit=Abflachen
@ -1402,8 +1406,8 @@ multiTool.delete=Löschen
multiTool.dragDropMessage=Ausgewählte Seite(n)
multiTool.undo=Rückgängig machen
multiTool.redo=Wiederherstellen
multiTool.duplicate=Duplicate
multiTool.svgNotSupported=SVG files are not supported in Multi Tool and were ignored.
multiTool.duplicate=Duplizieren
multiTool.svgNotSupported=SVG-Dateien werden in Multi Tool nicht unterstützt und wurden ignoriert.
#decrypt
decrypt.passwordPrompt=Diese Datei ist passwortgeschützt. Bitte geben Sie das Passwort ein:
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(z.B. 1,2,8 oder 4,7,12-16 oder 2n-1)
pdfToImage.includeAnnotations=Kommentare, Markierungen usw. einbeziehen
#pdfToVideo
pdfToVideo.title=PDF zu Video Slideshow
pdfToVideo.header=PDF zu Video Slideshow
pdfToVideo.videoFormat=Videoformat
pdfToVideo.secondsPerPage=Sekunden pro Seite
pdfToVideo.resolution=Auflösung
pdfToVideo.watermarkText=Wasserzeichen-Text (leer lassen für kein Wasserzeichen)
pdfToVideo.opacity=Deckkraft des Wasserzeichens (nur angewendet, wenn ein Wasserzeichen-Text angegeben ist)
pdfToVideo.resolutionOriginal=Original (PDF-Seitengröße beibehalten)
pdfToVideo.dpiLabel=DPI (Das Serverlimit beträgt {0} dpi)
pdfToVideo.submit=Konvertieren
#addPassword
addPassword.title=Passwort hinzufügen
addPassword.header=Passwort hinzufügen (Verschlüsseln)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF σε εικόνα
home.pdfToImage.desc=Μετατροπή PDF σε εικόνα. (PNG, JPEG, GIF)
pdfToImage.tags=μετατροπή,εικόνα,jpg,φωτογραφία
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Οργάνωση
home.pdfOrganiser.desc=Αφαίρεση/Αναδιάταξη σελίδων σε οποιαδήποτε σειρά
pdfOrganiser.tags=duplex,ζυγός,μονός,ταξινόμηση,μετακίνηση
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(π.χ. 1,2,8 ή 4,7,12-16 ή 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Προσθήκη κωδικού
addPassword.header=Προσθήκη κωδικού (Κρυπτογράφηση)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF to Image
home.pdfToImage.desc=Convert a PDF to a image. (PNG, JPEG, GIF, PSD)
pdfToImage.tags=conversion,img,jpg,picture,photo,psd,photoshop
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organise
home.pdfOrganiser.desc=Remove/Rearrange pages in any order
pdfOrganiser.tags=duplex,even,odd,sort,move
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Add Password
addPassword.header=Add password (Encrypt)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF to Image
home.pdfToImage.desc=Convert a PDF to a image. (PNG, JPEG, GIF, PSD)
pdfToImage.tags=conversion,img,jpg,picture,photo,psd,photoshop
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organize
home.pdfOrganiser.desc=Remove/Rearrange pages in any order
pdfOrganiser.tags=duplex,even,odd,sort,move
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Add Password
addPassword.header=Add password (Encrypt)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF a Imagen
home.pdfToImage.desc=Convertir un PDF a una imagen (PNG, JPEG, GIF)
pdfToImage.tags=conversión,img,jpg,imagen,fotografía
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organizador
home.pdfOrganiser.desc=Eliminar/Reorganizar páginas en cualquier orden
pdfOrganiser.tags=doble cara,pares,impares,ordenar,mover
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(por ejemplo 1,2,8 o 4,7,12-16 o 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Añadir contraseña
addPassword.header=Añadir contraseña (cifrar)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDFa irudi bihurtu
home.pdfToImage.desc=PDF bat irudi (PNG, JPEG, GIF) bihurtu
pdfToImage.tags=conversion,img,jpg,picture,photo,psd,photoshop
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Antolatzailea
home.pdfOrganiser.desc=Ezabatu/Berrantolatu orrialdeak edozein ordenatan
pdfOrganiser.tags=duplex,even,odd,sort,move
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Gehitu pasahitza
addPassword.header=Gehitu pasahitza (enkriptatu)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF به تصویر
home.pdfToImage.desc=تبدیل یک فایل PDF به یک تصویر. (PNG، JPEG، GIF)
pdfToImage.tags=تبدیل،عکس،jpg،تصویر،عکس
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=سازماندهی
home.pdfOrganiser.desc=حذف/بازآرایی صفحات به ترتیب دلخواه
pdfOrganiser.tags=دوطرفه،زوج،فرد،مرتب‌سازی،جابجایی
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(مثال: 1,2,8 یا 4,7,12-16 یا 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=افزودن گذرواژه
addPassword.header=افزودن گذرواژه (رمزنگاری)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF en image
home.pdfToImage.desc=Convertissez un PDF en image (PNG, JPEG, GIF).
pdfToImage.tags=conversion,img,jpg,image,photo
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organiser
home.pdfOrganiser.desc=Supprimez ou réorganisez les pages dans n'importe quel ordre.
pdfOrganiser.tags=organiser,recto-verso,duplex,even,odd,sort,move
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(par exemple : 1,2,8 ou 4,7,12-16 ou 2n-1)
pdfToImage.includeAnnotations=Inclure les annotations (commentaires, souligné etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Ajouter un mot de passe
addPassword.header=Ajouter un mot de passe

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF go íomhá
home.pdfToImage.desc=Tiontaigh PDF a íomhá. (PNG, JPEG, GIF)
pdfToImage.tags=comhshó, img, jpg, pictiúr, grianghraf
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Eagraigh
home.pdfOrganiser.desc=Bain/Atheagraigh na leathanaigh in ord ar bith
pdfOrganiser.tags=déphléacsacha, cothrom, corr, sórtáil, bogadh
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(m.sh. 1,2,8 nó 4,7,12-16 nó 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Cuir Pasfhocal leis
addPassword.header=Cuir pasfhocal leis (Criptigh)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF से छवि
home.pdfToImage.desc=PDF को छवि में बदलें। (PNG, JPEG, GIF)
pdfToImage.tags=रूपांतरण,img,jpg,चित्र,फोटो
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=व्यवस्थित करें
home.pdfOrganiser.desc=किसी भी क्रम में पृष्ठ निकालें/पुनर्व्यवस्थित करें
pdfOrganiser.tags=डुप्लेक्स,सम,विषम,क्रमबद्ध करें,मूव
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(जैसे 1,2,8 या 4,7,12-16 या 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=पासवर्ड जोड़ें
addPassword.header=पासवर्ड जोड़ें (एन्क्रिप्ट)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF u sliku
home.pdfToImage.desc=Pretvorite PDF u sliku (PNG, JPEG, GIF, PSD).
pdfToImage.tags=pretvorba,img,jpg,slika,fotografija,psd,photoshop
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organiziranje
home.pdfOrganiser.desc=Uklonite/preuredite stranice u bilo kojem redoslijedu
pdfOrganiser.tags=dvostrano,parno,neparno,sortiranje,pomicanje
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(npr. 1,2,8 ili 4,7,12-16 ili 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Dodaj lozinku
addPassword.header=Dodaj lozinku (šifriraj)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF képpé
home.pdfToImage.desc=PDF konvertálása képpé (PNG, JPEG, GIF).
pdfToImage.tags=konverzió,kép,jpg,fotó,fénykép
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Rendszerezés
home.pdfOrganiser.desc=Oldalak eltávolítása/átrendezése tetszőleges sorrendben
pdfOrganiser.tags=duplex,páros,páratlan,rendezés,mozgatás
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(pl. 1,2,8 vagy 4,7,12-16 vagy 2n-1)
pdfToImage.includeAnnotations=Megjegyzések belefoglalása (kommentek, kiemelések stb.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Jelszó hozzáadása
addPassword.header=Jelszó hozzáadása (Titkosítás)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF ke Gambar
home.pdfToImage.desc=Mengonversi PDF ke gambar. (PNG, JPEG, GIF)
pdfToImage.tags=konversi,img,jpg,gambar,foto
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Mengatur
home.pdfOrganiser.desc=Menghapus/Mengatur ulang halaman dalam urutan apa pun
pdfOrganiser.tags=dupleks,genap,ganjil,sortir,pindah
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(misalnya 1,2,8 atau 4,7,12-16 atau 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Tambahkan kata sandi
addPassword.header=Tambahkan kata sandi (Enkrip)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=Da PDF a immagine
home.pdfToImage.desc=Converti un PDF in un'immagine. (PNG, JPEG, GIF)
pdfToImage.tags=conversione,img,jpg,immagine,foto
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organizza
home.pdfOrganiser.desc=Rimuovi/Riordina le pagine in qualsiasi ordine.
pdfOrganiser.tags=duplex,pari,dispari,ordinamento,spostamento
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(es. 1,2,8 o 4,7,12-16 o 2n-1)
pdfToImage.includeAnnotations=Includi annotazioni (commenti, evidenziazioni, ecc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Aggiungi Password
addPassword.header=Aggiungi password (crittografa)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDFを画像に変換
home.pdfToImage.desc=PDFを画像 (PNG, JPEG, GIF) に変換します。
pdfToImage.tags=conversion,img,jpg,picture,photo,psd,photoshop
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=整理
home.pdfOrganiser.desc=ページの削除/並べ替えします。
pdfOrganiser.tags=duplex,even,odd,sort,move
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(例:1,2,8、4,7,12-16、2n-1)
pdfToImage.includeAnnotations=注釈(コメント、ハイライトなど)を含める
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=パスワードの追加
addPassword.header=パスワードの追加(暗号化)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF를 이미지로
home.pdfToImage.desc=PDF를 이미지로 변환합니다. (PNG, JPEG, GIF)
pdfToImage.tags=변환,이미지,jpg,사진
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=정리
home.pdfOrganiser.desc=원하는 순서로 페이지 제거/재배치
pdfOrganiser.tags=양면,짝수,홀수,정렬,이동
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(예: 1,2,8 또는 4,7,12-16 또는 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=비밀번호 추가
addPassword.header=비밀번호 추가 (암호화)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF ചിത്രത്തിലേക്ക്
home.pdfToImage.desc=ഒരു PDF ചിത്രത്തിലേക്ക് മാറ്റുക. (PNG, JPEG, GIF)
pdfToImage.tags=പരിവർത്തനം,img,jpg,ചിത്രം,ഫോട്ടോ
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=ക്രമീകരിക്കുക
home.pdfOrganiser.desc=ഏത് ക്രമത്തിലും പേജുകൾ നീക്കം ചെയ്യുക/പുനഃക്രമീകരിക്കുക
pdfOrganiser.tags=ഡ്യൂപ്ലെക്സ്,ഇരട്ട,ഒറ്റ,അടുക്കുക,നീക്കുക
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(ഉദാ. 1,2,8 അല്ലെങ്കിൽ 4,7,12-1
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=പാസ്വേഡ് ചേർക്കുക
addPassword.header=പാസ്വേഡ് ചേർക്കുക (എൻക്രിപ്റ്റ് ചെയ്യുക)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF naar Afbeelding
home.pdfToImage.desc=Converteer een PDF naar een afbeelding. (PNG, JPEG, GIF)
pdfToImage.tags=conversie,img,jpg,foto
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organiseren
home.pdfOrganiser.desc=Verwijder/herschik pagina's in een volgorde naar keus
pdfOrganiser.tags=duplex,even oneven,sorteren,verplaatsen
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(bijv. 1,2,8 of 4,7,12-16 of 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Wachtwoord toevoegen
addPassword.header=Wachtwoord toevoegen (Versleutelen)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF til Bilde
home.pdfToImage.desc=Konverter en PDF til et bilde. (PNG, JPEG, GIF)
pdfToImage.tags=konvertering,bilde,jpg,foto
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organiser
home.pdfOrganiser.desc=Fjern/omorganiser sider i hvilken som helst rekkefølge
pdfOrganiser.tags=dupleks,par,single,sorter,flytt
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(f.eks. 1,2,8 eller 4,7,12-16 eller 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Legg til passord
addPassword.header=Legg til passord (Krypter)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF na Obraz
home.pdfToImage.desc=Konwertuj plik PDF na obraz (PNG, JPEG, GIF).
pdfToImage.tags=konwersja,img,jpg,obraz,zdjęcie
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Uporządkuj
home.pdfOrganiser.desc=Usuń/Zmień kolejność stron w dowolnej kolejności
pdfOrganiser.tags=duplex,parzyste,nieparzyste,sortuj,przenieś
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(przykład 1,2,8 lub 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Dodaj hasło
addPassword.header=Dodaj hasło (zaszyfruj)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF para Imagem
home.pdfToImage.desc=Converter PDF em uma imagem (PNG, JPG, GIF e outros).
pdfToImage.tags=conversão,img,jpg,imagem,foto
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organizar Páginas
home.pdfOrganiser.desc=Remover/reorganizar as páginas de diversas formas diferentes.
pdfOrganiser.tags=duplex,par,ímpar,ordenar,mover
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(por exemplo 1,2,8 ou 4,7,12-16 ou 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Proteger PDF
addPassword.header=Proteger PDF (Criptografar)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF para Imagem
home.pdfToImage.desc=Converter um PDF para uma imagem. (PNG, JPEG, GIF)
pdfToImage.tags=conversão,img,jpg,imagem,foto
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organizar
home.pdfOrganiser.desc=Remover/Reorganizar páginas em qualquer ordem
pdfOrganiser.tags=duplex,par,ímpar,ordenar,mover
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(ex. 1,2,8 ou 4,7,12-16 ou 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Adicionar Palavra-passe
addPassword.header=Adicionar palavra-passe (Encriptar)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF în Imagine
home.pdfToImage.desc=Convertește un fișier PDF în imagine (PNG, JPEG, GIF).
pdfToImage.tags=conversie,img,jpg,poză,fotografie
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organizează
home.pdfOrganiser.desc=Elimină/rearanjează pagini în orice ordine
pdfOrganiser.tags=duplex,par,impar,sortează,mută
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(ex. 1,2,8 sau 4,7,12-16 sau 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Adaugă parolă
addPassword.header=Adaugă o parolă (Criptare)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF в изображение
home.pdfToImage.desc=Преобразование PDF в изображение (PNG, JPEG, GIF).
pdfToImage.tags=png,jpeg,gif,конвертация,изображение,картинка,фото
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Организация
home.pdfOrganiser.desc=Удаление/переупорядочивание страниц в любом порядке
pdfOrganiser.tags=двусторонняя печать,четные,нечетные,сортировка,перемещение
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(например, 1,2,8 или 4,7,12-16 или 2n-1)
pdfToImage.includeAnnotations=Добавьте аннотации (комментарии, основные моменты и т.д.).
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Добавить пароль
addPassword.header=Добавить пароль (Шифрование)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF na obrázok
home.pdfToImage.desc=Konvertujte PDF na obrázok. (PNG, JPEG, GIF)
pdfToImage.tags=konverzia,img,jpg,obrázok,fotografia
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organizovať
home.pdfOrganiser.desc=Odstráňte/preusporiadajte stránky v ľubovoľnom poradí
pdfOrganiser.tags=duplex,nepárne,párne,zoradiť,posunúť
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(napr. 1,2,8 alebo 4,7,12-16 alebo 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Pridať heslo
addPassword.header=Pridať heslo (Zašifrovať)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF v sliko
home.pdfToImage.desc=Pretvori PDF v sliko. (PNG, JPEG, GIF)
pdfToImage.tags=pretvorba,img,jpg,slika,fotografija
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organiziraj
home.pdfOrganiser.desc=Odstrani/Prerazporedi strani v poljubnem vrstnem redu
pdfOrganiser.tags=dvostranski,sodi,lihi,razvrsti,premakni
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(npr. 1,2,8 ali 4,7,12-16 ali 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Dodaj geslo
addPassword.header=Dodaj geslo (Šifriraj)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF u Sliku
home.pdfToImage.desc=Konvertovanje PDF u sliku (PNG, JPEG, GIF)
pdfToImage.tags=konverzija,img,jpg,slika,foto
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Organizacija
home.pdfOrganiser.desc=Uklanjanje/premeštanje stranica po bilo kom redosledu
pdfOrganiser.tags=dupleks,parne,neparne,sortiranje,pomeranje
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(npr. 1,2,8 ili 4,7,12-16 ili 2n-1)
pdfToImage.includeAnnotations=Uključi napomene (komentare, isticanja itd.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Dodaj šifru
addPassword.header=Dodaj šifru (enkripcija)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF till bild
home.pdfToImage.desc=Konvertera en PDF till en bild. (PNG, JPEG, GIF)
pdfToImage.tags=konvertering,img,jpg,bild,foto
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Ordna
home.pdfOrganiser.desc=Ta bort/ordna om sidor i valfri ordning
pdfOrganiser.tags=duplex,jämn,udda,sortera,flytta
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(t.ex. 1,2,8 eller 4,7,12-16 eller 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Lägg till lösenord
addPassword.header=Lägg till lösenord (kryptera)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF เป็นรูปภาพ
home.pdfToImage.desc=แปลง PDF เป็นรูปภาพ (PNG, JPEG, GIF)
pdfToImage.tags=การแปลง, รูปภาพ, JPG, ภาพ, รูปถ่าย
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=จัดระเบียบ
home.pdfOrganiser.desc=ลบ/จัดเรียงหน้าต่างๆ ในลำดับที่ต้องการ
pdfOrganiser.tags=สองหน้า, คู่ขนาน, เรียงลำดับ, เคลื่อนย้าย
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(เช่น 1,2,8 หรือ 4,7,12-16 หรือ 2
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=เพิ่มรหัสผ่าน
addPassword.header=เพิ่มรหัสผ่าน (เข้ารหัส)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF'den Resme
home.pdfToImage.desc=PDF'yi bir resme dönüştürün. (PNG, JPEG, GIF)
pdfToImage.tags=dönüşüm,img,jpg,fotoğraf,resim
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Düzenle
home.pdfOrganiser.desc=Sayfaları herhangi bir sırayla kaldırın/düzenleyin
pdfOrganiser.tags=çift,çift,yan,yana,sırala,taşı
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(örneğin 1,2,8 veya 4,7,12-16 ya da 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Parola Ekle
addPassword.header=Parola Ekle (Şifrele)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF в зображення
home.pdfToImage.desc=Перетворення PDF в зображення. (PNG, JPEG, GIF)
pdfToImage.tags=конвертація,зображення,jpg,картинка,фото
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Реорганізація
home.pdfOrganiser.desc=Видалення/перестановка сторінок у будь-якому порядку
pdfOrganiser.tags=двосторонній друк,парні,непарні,сортування,переміщення
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(наприклад 1,2,8 або 4,7,12-16 або 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Додати пароль
addPassword.header=Додати пароль (зашифрувати)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF sang Hình ảnh
home.pdfToImage.desc=Chuyển đổi PDF sang hình ảnh. (PNG, JPEG, GIF)
pdfToImage.tags=chuyển đổi,img,jpg,hình ảnh,ảnh
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=Sắp xếp
home.pdfOrganiser.desc=Xóa/Sắp xếp lại trang theo bất kỳ thứ tự nào
pdfOrganiser.tags=duplex,chẵn,lẻ,sắp xếp,di chuyển
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(ví dụ: 1,2,8 hoặc 4,7,12-16 hoặc 2n-1)
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=Thêm mật khẩu
addPassword.header=Thêm mật khẩu (Mã hóa)

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=转换 PDF 到图像
home.pdfToImage.desc=将 PDF 转换为图像PNG、JPEG、GIF
pdfToImage.tags=转换、图像、JPG、图片、照片
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=整理
home.pdfOrganiser.desc=按任意顺序删除/重新排列页面。
pdfOrganiser.tags=双面、偶数、奇数、排序、移动
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=例如1,2,8 或 4,7,12-16 或 2n-1
pdfToImage.includeAnnotations=Include annotations (comments, highlights etc.)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=添加密码
addPassword.header=添加密码(加密)。

View File

@ -628,6 +628,10 @@ home.pdfToImage.title=PDF 轉圖片
home.pdfToImage.desc=將 PDF 轉換為圖片PNG、JPEG、GIF
pdfToImage.tags=轉換,img,jpg,圖片,照片
home.PDFToVideo.title=PDF to Video Slideshow
home.PDFToVideo.desc=Convert a PDF into a slideshow-style video.
PDFToVideo.tags=conversion,video,slideshow,presentation
home.pdfOrganiser.title=整理
home.pdfOrganiser.desc=移除或重新排列頁面順序
pdfOrganiser.tags=雙面,偶數,奇數,排序,移動
@ -1512,6 +1516,19 @@ pdfToImage.placeholder=(例如 1,2,8 或 4,7,12-16 或 2n-1
pdfToImage.includeAnnotations=包含註釋(評論、醒目提示等)
#pdfToVideo
pdfToVideo.title=PDF to Video Slideshow
pdfToVideo.header=PDF to Video Slideshow
pdfToVideo.videoFormat=Video format
pdfToVideo.secondsPerPage=Seconds per page
pdfToVideo.resolution=Resolution
pdfToVideo.watermarkText=Watermark Text (empty for no watermark)
pdfToVideo.opacity=Opacity of the watermark (only applied if a watermark text is specified)
pdfToVideo.resolutionOriginal=Original (keep PDF page size)
pdfToVideo.dpiLabel=DPI (The server limit is {0} dpi)
pdfToVideo.submit=Convert
#addPassword
addPassword.title=新增密碼
addPassword.header=新增密碼(加密)

View File

@ -0,0 +1,84 @@
<!DOCTYPE html>
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}"
xmlns:th="https://www.thymeleaf.org">
<head>
<th:block th:insert="~{fragments/common :: head(title=#{pdfToVideo.title}, header=#{pdfToVideo.header})}"></th:block>
<script th:inline="javascript">
document.addEventListener("DOMContentLoaded", function () {
const maxDPI = /*[[${maxDPI}]]*/ 500;
const labelTemplate = /*[[#{pdfToVideo.dpiLabel}]]*/ "DPI (The server limit is {0} dpi)";
const dpiLabel = document.querySelector('label[for="dpi"]');
if (dpiLabel) {
dpiLabel.textContent = labelTemplate.replace("{0}", maxDPI);
}
const dpiInput = document.getElementById("dpi");
if (dpiInput) {
dpiInput.setAttribute("max", maxDPI);
}
});
</script>
</head>
<body>
<th:block th:insert="~{fragments/common :: game}"></th:block>
<div id="page-container">
<div id="content-wrap">
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
<br><br>
<div class="container">
<div class="row justify-content-center">
<div class="col-md-6 bg-card">
<div class="tool-header">
<span class="material-symbols-rounded tool-header-icon convert">movie</span>
<span class="tool-header-text" th:text="#{pdfToVideo.header}"></span>
</div>
<p th:text="#{processTimeWarning}"></p>
<form method="post" enctype="multipart/form-data" th:action="@{'/api/v1/convert/pdf/video'}">
<div
th:replace="~{fragments/common :: fileSelector(name='fileInput', multipleInputsForSingleRequest=false, accept='application/pdf')}">
</div>
<div class="mb-3">
<label for="videoFormat" th:text="#{pdfToVideo.videoFormat}"></label>
<select id="videoFormat" class="form-control" name="videoFormat">
<option value="mp4">MP4</option>
<option value="webm">WebM</option>
</select>
</div>
<div class="mb-3">
<label for="secondsPerPage" th:text="#{pdfToVideo.secondsPerPage}"></label>
<input id="secondsPerPage" type="number" class="form-control" name="secondsPerPage" min="1" max="30" value="3"
required>
</div>
<div class="mb-3">
<label for="resolution" th:text="#{pdfToVideo.resolution}"></label>
<select id="resolution" class="form-control" name="resolution">
<option value="ORIGINAL" th:text="#{pdfToVideo.resolutionOriginal}"></option>
<option value="1080p">1080p</option>
<option value="720p">720p</option>
<option value="480p">480p</option>
</select>
</div>
<div class="mb-3">
<label for="dpi">DPI</label>
<input id="dpi" type="number" class="form-control" name="dpi" min="72" max="500" value="150" required>
</div>
<div class="mb-3">
<label for="watermarkText" th:text="#{pdfToVideo.watermarkText}"></label>
<input id="watermarkText" type="text" class="form-control" name="watermarkText" placeholder="Stirling Software">
</div>
<div class="mb-3">
<label for="opacity" th:text="#{pdfToVideo.opacity}"></label>
<input id="opacity" type="number" step="0.01" class="form-control" name="opacity" min="0.0" max="1.0" value="0.1">
</div>
<button type="submit" id="submitBtn" class="btn btn-primary" th:text="#{pdfToVideo.submit}"></button>
</form>
</div>
</div>
</div>
</div>
<th:block th:insert="~{fragments/footer.html :: footer}"></th:block>
</div>
</body>
</html>

View File

@ -113,6 +113,9 @@
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('pdf-to-vector', 'stroke_full', 'home.pdfToVector.title', 'home.pdfToVector.desc', 'pdfToVector.tags', 'convert')}">
</div>
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('pdf-to-video', 'movie', 'home.PDFToVideo.title', 'home.PDFToVideo.desc', 'PDFToVideo.tags', 'convert')}">
</div>
</div>
</div>
@ -175,6 +178,9 @@
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('pdf-to-vector', 'stroke_full', 'home.pdfToVector.title', 'home.pdfToVector.desc', 'pdfToVector.tags', 'convert')}">
</div>
<div
th:replace="~{fragments/navbarEntry :: navbarEntry('pdf-to-video', 'movie', 'home.PDFToVideo.title', 'home.PDFToVideo.desc', 'PDFToVideo.tags', 'convert')}">
</div>
</div>
</div>
<div id="groupSecurity" class="feature-group">

View File

@ -195,6 +195,9 @@
<div
th:replace="~{fragments/card :: card(id='pdf-to-csv', cardTitle=#{home.tableExtraxt.title}, cardText=#{home.tableExtraxt.desc}, cardLink='pdf-to-csv', toolIcon='csv', tags=#{tableExtraxt.tags}, toolGroup='convert')}">
</div>
<div
th:replace="~{fragments/card :: card(id='pdf-to-video', cardTitle=#{home.PDFToVideo.title}, cardText=#{home.PDFToVideo.desc}, cardLink='pdf-to-video', toolIcon='movie', tags=#{PDFToVideo.tags}, toolGroup='convert')}">
</div>
</div>
</div>

View File

@ -182,6 +182,7 @@ processExecutor:
calibreSessionLimit: 1
ghostscriptSessionLimit: 8
ocrMyPdfSessionLimit: 2
ffmpegSessionLimit: 2
timeoutMinutes: # Process executor timeout in minutes
libreOfficetimeoutMinutes: 30
pdfToHtmltimeoutMinutes: 20
@ -193,3 +194,4 @@ processExecutor:
qpdfTimeoutMinutes: 30
ghostscriptTimeoutMinutes: 30
ocrMyPdfTimeoutMinutes: 30
ffmpegTimeoutMinutes: 30