From 2a7f837b55ca35df81989e15916c3ba62a34a759 Mon Sep 17 00:00:00 2001 From: Edwin Jakobs Date: Fri, 10 Jul 2020 16:50:45 +0200 Subject: [PATCH] [orx-video-profiles] Add orx-video-profiles --- build.gradle | 5 +- orx-video-profiles/README.md | 6 ++ orx-video-profiles/build.gradle | 19 ++++++ .../src/demo/kotlin/DemoGIF01.kt | 16 +++++ .../src/demo/kotlin/DemoProres01.kt | 15 +++++ .../src/main/kotlin/GIFProfile.kt | 10 ++++ .../src/main/kotlin/ProresProfile.kt | 25 ++++++++ .../src/main/kotlin/X265Profile.kt | 60 +++++++++++++++++++ settings.gradle | 3 +- 9 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 orx-video-profiles/README.md create mode 100644 orx-video-profiles/build.gradle create mode 100644 orx-video-profiles/src/demo/kotlin/DemoGIF01.kt create mode 100644 orx-video-profiles/src/demo/kotlin/DemoProres01.kt create mode 100644 orx-video-profiles/src/main/kotlin/GIFProfile.kt create mode 100644 orx-video-profiles/src/main/kotlin/ProresProfile.kt create mode 100644 orx-video-profiles/src/main/kotlin/X265Profile.kt diff --git a/build.gradle b/build.gradle index 53fd0be6..647387bf 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ buildscript { apply plugin: 'org.jetbrains.dokka' project.ext { - openrndrVersion = "0.3.43-rc.15" + openrndrVersion = "0.3.44-rc.1" kotlinVersion = "1.3.72" spekVersion = "2.0.10" libfreenectVersion = "0.5.7-1.5.3" @@ -181,6 +181,9 @@ task collectScreenshots { continue if (sub.name == "orx-chataigne") continue + if (sub.name == "orx-video-profiles") + continue + def set = sub.sourceSets.demo def ucl = new URLClassLoader(set.runtimeClasspath.collect { it.toURI().toURL() } as URL[]) diff --git a/orx-video-profiles/README.md b/orx-video-profiles/README.md new file mode 100644 index 00000000..4052d068 --- /dev/null +++ b/orx-video-profiles/README.md @@ -0,0 +1,6 @@ +# orx-video-profiles + +A collection of `VideoWriterProfile` implementations that can be used with `ScreenRecorder` and `VideoWriter` + +## Usage + diff --git a/orx-video-profiles/build.gradle b/orx-video-profiles/build.gradle new file mode 100644 index 00000000..a0d7205c --- /dev/null +++ b/orx-video-profiles/build.gradle @@ -0,0 +1,19 @@ +sourceSets { + demo { + java { + srcDirs = ["src/demo/kotlin"] + compileClasspath += main.getCompileClasspath() + runtimeClasspath += main.getRuntimeClasspath() + } + } +} + +dependencies { + demoImplementation("org.openrndr:openrndr-core:$openrndrVersion") + demoImplementation("org.openrndr:openrndr-extensions:$openrndrVersion") + demoImplementation("org.openrndr:openrndr-ffmpeg:$openrndrVersion") + demoRuntimeOnly("org.openrndr:openrndr-gl3:$openrndrVersion") + demoRuntimeOnly("org.openrndr:openrndr-gl3-natives-$openrndrOS:$openrndrVersion") + implementation("org.openrndr:openrndr-ffmpeg:$openrndrVersion") + demoImplementation(sourceSets.getByName("main").output) +} \ No newline at end of file diff --git a/orx-video-profiles/src/demo/kotlin/DemoGIF01.kt b/orx-video-profiles/src/demo/kotlin/DemoGIF01.kt new file mode 100644 index 00000000..38728cd2 --- /dev/null +++ b/orx-video-profiles/src/demo/kotlin/DemoGIF01.kt @@ -0,0 +1,16 @@ +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.extra.videoprofiles.GIFProfile +import org.openrndr.extra.videoprofiles.ProresProfile +import org.openrndr.ffmpeg.ScreenRecorder + +fun main() = application { + program { + extend(ScreenRecorder()) { + profile = GIFProfile() + } + extend { + drawer.clear(ColorRGBa.GREEN) + } + } +} \ No newline at end of file diff --git a/orx-video-profiles/src/demo/kotlin/DemoProres01.kt b/orx-video-profiles/src/demo/kotlin/DemoProres01.kt new file mode 100644 index 00000000..388ab596 --- /dev/null +++ b/orx-video-profiles/src/demo/kotlin/DemoProres01.kt @@ -0,0 +1,15 @@ +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.extra.videoprofiles.ProresProfile +import org.openrndr.ffmpeg.ScreenRecorder + +fun main() = application { + program { + extend(ScreenRecorder()) { + profile = ProresProfile() + } + extend { + drawer.clear(ColorRGBa.GREEN) + } + } +} \ No newline at end of file diff --git a/orx-video-profiles/src/main/kotlin/GIFProfile.kt b/orx-video-profiles/src/main/kotlin/GIFProfile.kt new file mode 100644 index 00000000..172d7710 --- /dev/null +++ b/orx-video-profiles/src/main/kotlin/GIFProfile.kt @@ -0,0 +1,10 @@ +package org.openrndr.extra.videoprofiles +import org.openrndr.ffmpeg.VideoWriterProfile + +class GIFProfile : VideoWriterProfile() { + override val fileExtension = "gif" + + override fun arguments(): Array { + return arrayOf("-vf", "split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse=dither=none:diff_mode=rectangle") + } +} \ No newline at end of file diff --git a/orx-video-profiles/src/main/kotlin/ProresProfile.kt b/orx-video-profiles/src/main/kotlin/ProresProfile.kt new file mode 100644 index 00000000..5bce24b4 --- /dev/null +++ b/orx-video-profiles/src/main/kotlin/ProresProfile.kt @@ -0,0 +1,25 @@ +package org.openrndr.extra.videoprofiles + +import org.openrndr.ffmpeg.VideoWriterProfile + +class ProresProfile : VideoWriterProfile() { + enum class Profile(val argument:String) { + PROXY("0"), + LT("1"), + SQ("2"), + HQ("3"), + HQ4444("4444") + } + + override val fileExtension: String = "mov" + var profile = Profile.SQ + var codec = "prores_ks" + + override fun arguments(): Array { + val vcodec = arrayOf("-vcodec", codec) + val profile = arrayOf("-profile:v", profile.argument) + val filters = arrayOf("-vf", "vflip") + val audio = arrayOf("-an") + return vcodec + profile + filters + audio + } +} \ No newline at end of file diff --git a/orx-video-profiles/src/main/kotlin/X265Profile.kt b/orx-video-profiles/src/main/kotlin/X265Profile.kt new file mode 100644 index 00000000..3ac9e2b2 --- /dev/null +++ b/orx-video-profiles/src/main/kotlin/X265Profile.kt @@ -0,0 +1,60 @@ +package org.openrndr.extra.videoprofiles +import org.openrndr.ffmpeg.VideoWriterProfile + +class X265Profile : VideoWriterProfile() { + internal var mode = WriterMode.Normal + internal var constantRateFactor = 28 + var hlg = false + + enum class WriterMode { + Normal, + Lossless + } + + fun mode(mode: WriterMode): X265Profile { + this.mode = mode + return this + } + + /** + * Sets the constant rate factor + * @param constantRateFactor the constant rate factor (default is 28) + * @return + */ + fun constantRateFactor(constantRateFactor: Int): X265Profile { + this.constantRateFactor = constantRateFactor + return this + } + + override val fileExtension = "mp4" + + + override fun arguments(): Array { + when (mode) { + WriterMode.Normal -> { + return if (!hlg) { + arrayOf("-pix_fmt", "yuv420p", // this will produce videos that are playable by quicktime + "-vf", "vflip", + "-an", "-vcodec", "libx265", "-crf", "" + constantRateFactor) + } else { + arrayOf( // this will produce videos that are playable by quicktime + "-an", "" + + "-vcodec", "libx265", + "-pix_fmt", "yuv420p10le", + "-color_primaries", "bt2020", + "-colorspace", "bt2020_ncl", + "-color_trc", "arib-std-b67", + "-crf", "" + constantRateFactor) + // transfer=arib-std-b67 + } + } + WriterMode.Lossless -> { + return arrayOf("-pix_fmt", "yuv420p10", // this will produce videos that are playable by quicktime + "-an", "-vcodec", "libx265", "-preset", "ultrafast") + } + else -> { + throw RuntimeException("unsupported write mode") + } + } + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 7d13dfd7..ff096bff 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,6 +3,7 @@ rootProject.name = 'orx' include 'openrndr-demos', 'orx-boofcv', 'orx-camera', + 'orx-chataigne', 'orx-compositor', 'orx-dnk3', 'orx-easing', @@ -46,5 +47,5 @@ include 'openrndr-demos', 'orx-kinect-v1-natives-macos', 'orx-kinect-v1-natives-windows', 'orx-kinect-v1-demo', - 'orx-chataigne' + 'orx-video-profiles'