Skip to content

Commit acc755b

Browse files
Provide options to choose watermark positions.
1 parent 0760507 commit acc755b

File tree

5 files changed

+84
-19
lines changed

5 files changed

+84
-19
lines changed

SSffmpegVideoOperation/src/main/java/com/simform/videooperations/FFmpegQueryExtension.kt

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,42 @@ public class FFmpegQueryExtension {
6262
* posX = X position of water-mark in percentage (1% to 100%)
6363
* posY = Y position of water-mark in percentage (1% to 100%)
6464
*/
65-
fun addVideoWaterMark(inputVideo: String, imageInput: String, posX: Float?, posY: Float?, output: String): Array<String> {
66-
val inputs: ArrayList<String> = ArrayList()
67-
inputs.apply {
68-
add("-i")
69-
add(inputVideo)
70-
add("-i")
71-
add(imageInput)
72-
add("-filter_complex")
73-
add("overlay=$posX:$posY")
74-
add("-preset")
75-
add("ultrafast")
76-
add(output)
65+
fun addVideoWaterMark(
66+
inputVideo: String,
67+
imageInput: String,
68+
posX: Float?, // Optional custom X coordinate
69+
posY: Float?, // Optional custom Y coordinate
70+
output: String,
71+
position: String?, // e.g. "center", "fill", etc.
72+
): Array<String> {
73+
val inputs = arrayListOf("-i", inputVideo, "-i", imageInput)
74+
75+
val filterComplex = when (position?.lowercase()) {
76+
"fill" -> "[1:v][0:v]scale2ref=w=iw:h=ih[wm][base];[base][wm]overlay=0:0"
77+
"crop" -> "[1:v][0:v]scale2ref=w='if(gt(a,iw/ih),iw,-1)':h='if(gt(a,iw/ih),-1,ih)'[wm][base];[base][wm]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2"
78+
"center" -> "overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2"
79+
"top-left" -> "overlay=0:0"
80+
"top-right" -> "overlay=W-w:0"
81+
"bottom-left" -> "overlay=0:H-h"
82+
"bottom-right" -> "overlay=W-w:H-h"
83+
else -> {
84+
// Use custom x and y if provided, else default to 0
85+
val x = posX?.toString() ?: "0"
86+
val y = posY?.toString() ?: "0"
87+
"overlay=$x:$y"
88+
}
7789
}
78-
return inputs.toArray(arrayOfNulls<String>(inputs.size))
90+
91+
inputs.addAll(
92+
listOf(
93+
"-filter_complex", filterComplex,
94+
"-preset", "ultrafast",
95+
"-y", // Overwrite output if exists
96+
output
97+
)
98+
)
99+
100+
return inputs.toArray(arrayOfNulls(inputs.size))
79101
}
80102

81103
fun addTextOnVideo(inputVideo: String, textInput: String, posX: Float?, posY: Float?, fontPath: String, isTextBackgroundDisplay: Boolean, fontSize: Int, fontcolor: String, output: String): Array<String> {

app/src/main/java/com/simform/videoimageeditor/videoProcessActivity/AddWaterMarkOnVideoActivity.kt

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import android.media.MediaMetadataRetriever
55
import android.os.Build
66
import android.text.TextUtils
77
import android.view.View
8+
import android.widget.ArrayAdapter
9+
import android.widget.Spinner
810
import android.widget.Toast
911
import androidx.activity.result.PickVisualMediaRequest
1012
import androidx.activity.result.contract.ActivityResultContracts
@@ -34,6 +36,21 @@ class AddWaterMarkOnVideoActivity : BaseActivity(R.layout.activity_add_water_mar
3436
binding.btnVideoPath.setOnClickListener(this)
3537
binding.btnImagePath.setOnClickListener(this)
3638
binding.btnAdd.setOnClickListener(this)
39+
setUpSpinner()
40+
}
41+
42+
private fun setUpSpinner() {
43+
val positionOptions = listOf(
44+
"custom", // for x/y coordinates
45+
"center",
46+
"fill",
47+
"crop",
48+
"top-left",
49+
"top-right",
50+
"bottom-left",
51+
"bottom-right"
52+
)
53+
binding.spinner.adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, positionOptions)
3754
}
3855

3956
override fun onClick(v: View?) {
@@ -62,6 +79,10 @@ class AddWaterMarkOnVideoActivity : BaseActivity(R.layout.activity_add_water_mar
6279
!isWaterMarkImageSelected -> {
6380
Toast.makeText(this, getString(R.string.input_image_validate_message), Toast.LENGTH_SHORT).show()
6481
}
82+
binding.spinner.selectedItem.toString() != "custom" -> {
83+
processStart()
84+
addWaterMarkProcess()
85+
}
6586
TextUtils.isEmpty(binding.edtXPos.text.toString()) -> {
6687
Toast.makeText(this, getString(R.string.x_position_validation), Toast.LENGTH_SHORT).show()
6788
}
@@ -125,12 +146,26 @@ class AddWaterMarkOnVideoActivity : BaseActivity(R.layout.activity_add_water_mar
125146
private fun addWaterMarkProcess() {
126147
val outputPath = getFilePath(this, VIDEO)
127148
val xPos = width?.let {
128-
(binding.edtXPos.text.toString().toFloat().times(it)).div(100)
149+
if (binding.edtXPos.text.isEmpty()) null
150+
else
151+
(binding.edtXPos.text?.toString()?.toFloat()?.times(it))?.div(100)
129152
}
130153
val yPos = height?.let {
131-
(binding.edtYPos.text.toString().toFloat().times(it)).div(100)
154+
if (binding.edtYPos.text.isEmpty()) null
155+
else
156+
(binding.edtYPos.text?.toString()?.toFloat()?.times(it))?.div(100)
132157
}
133-
val query = ffmpegQueryExtension.addVideoWaterMark(binding.tvInputPathVideo.text.toString(), binding.tvInputPathImage.text.toString(), xPos, yPos, outputPath)
158+
159+
val selectedPosition = binding.spinner.selectedItem.toString()
160+
161+
val query = ffmpegQueryExtension.addVideoWaterMark(
162+
binding.tvInputPathVideo.text.toString(),
163+
binding.tvInputPathImage.text.toString(),
164+
position = if (selectedPosition == "custom") null else selectedPosition,
165+
posX = if (selectedPosition == "custom") xPos else null,
166+
posY = if (selectedPosition == "custom") yPos else null,
167+
output = outputPath
168+
)
134169
CallBackOfQuery().callQuery(query, object : FFmpegCallBack {
135170
override fun process(logMessage: LogMessage) {
136171
binding.tvOutputPath.text = logMessage.text

app/src/main/java/com/simform/videoimageeditor/videoProcessActivity/CompressVideoActivity.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import android.media.MediaMetadataRetriever
55
import android.os.Build
66
import android.view.View
77
import android.widget.Toast
8-
import androidx.activity.enableEdgeToEdge
98
import androidx.activity.result.PickVisualMediaRequest
109
import androidx.activity.result.contract.ActivityResultContracts
1110
import com.jaiselrahman.filepicker.model.MediaFile

app/src/main/java/com/simform/videoimageeditor/videoProcessActivity/CutVideoUsingTimeActivity.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import android.text.TextUtils
66
import android.view.View
77
import android.widget.TextView
88
import android.widget.Toast
9-
import androidx.activity.enableEdgeToEdge
109
import androidx.activity.result.PickVisualMediaRequest
1110
import androidx.activity.result.contract.ActivityResultContracts
1211
import com.jaiselrahman.filepicker.model.MediaFile

app/src/main/res/layout/activity_add_water_mark_on_video.xml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,16 @@
105105
app:layout_constraintTop_toBottomOf="@+id/txtHintContain"
106106
app:layout_constraintEnd_toEndOf="parent"/>
107107

108+
109+
<androidx.appcompat.widget.AppCompatSpinner
110+
android:id="@+id/spinner"
111+
android:layout_width="match_parent"
112+
android:layout_height="wrap_content"
113+
android:spinnerMode="dropdown"
114+
app:layout_constraintTop_toBottomOf="@id/edtXPos"
115+
app:layout_constraintStart_toStartOf="@id/edtXPos"
116+
app:layout_constraintEnd_toEndOf="@id/edtYPos" />
117+
108118
<Button
109119
android:id="@+id/btnAdd"
110120
android:layout_width="0dp"
@@ -114,7 +124,7 @@
114124
android:layout_margin="10dp"
115125
android:textColor="@android:color/white"
116126
app:layout_constraintStart_toStartOf="parent"
117-
app:layout_constraintTop_toBottomOf="@+id/edtYPos"
127+
app:layout_constraintTop_toBottomOf="@+id/spinner"
118128
app:layout_constraintEnd_toEndOf="parent"/>
119129

120130
<TextView

0 commit comments

Comments
 (0)