Skip to content

Commit fdab622

Browse files
Provide options to choose watermark positions.
1 parent 369fe7b commit fdab622

File tree

5 files changed

+85
-21
lines changed

5 files changed

+85
-21
lines changed

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

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,41 @@ 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+
return inputs.toArray(arrayOfNulls(inputs.size))
79100
}
80101

81102
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: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,19 @@ import android.media.MediaMetadataRetriever
55
import android.os.Build
66
import android.text.TextUtils
77
import android.view.View
8+
import android.widget.ArrayAdapter
89
import android.widget.Toast
910
import androidx.activity.result.PickVisualMediaRequest
1011
import androidx.activity.result.contract.ActivityResultContracts
1112
import com.jaiselrahman.filepicker.model.MediaFile
1213
import com.simform.videoimageeditor.BaseActivity
1314
import com.simform.videoimageeditor.R
1415
import com.simform.videoimageeditor.databinding.ActivityAddWaterMarkOnVideoBinding
16+
import com.simform.videoimageeditor.utils.enableEdgeToEdge
1517
import com.simform.videooperations.CallBackOfQuery
1618
import com.simform.videooperations.Common
1719
import com.simform.videooperations.Common.VIDEO
1820
import com.simform.videooperations.Common.getFilePath
19-
import com.simform.videooperations.Common.selectFile
2021
import com.simform.videooperations.FFmpegCallBack
2122
import com.simform.videooperations.LogMessage
2223
import java.util.concurrent.CompletableFuture.runAsync
@@ -29,12 +30,14 @@ class AddWaterMarkOnVideoActivity : BaseActivity(R.layout.activity_add_water_mar
2930
override fun initialization() {
3031
binding = ActivityAddWaterMarkOnVideoBinding.inflate(layoutInflater)
3132
setContentView(binding.root)
32-
33+
enableEdgeToEdge(binding.toolbar.root)
3334
binding.apply {
3435
btnVideoPath.setOnClickListener(this@AddWaterMarkOnVideoActivity)
3536
btnImagePath.setOnClickListener(this@AddWaterMarkOnVideoActivity)
3637
btnAdd.setOnClickListener(this@AddWaterMarkOnVideoActivity)
38+
toolbar.textTitle.text = getString(R.string.add_water_mark_on_video)
3739
}
40+
setUpSpinner()
3841
}
3942

4043
override fun onClick(v: View?) {
@@ -63,6 +66,10 @@ class AddWaterMarkOnVideoActivity : BaseActivity(R.layout.activity_add_water_mar
6366
!isWaterMarkImageSelected -> {
6467
Toast.makeText(this, getString(R.string.input_image_validate_message), Toast.LENGTH_SHORT).show()
6568
}
69+
binding.spinner.selectedItem.toString() != "custom" -> {
70+
processStart()
71+
addWaterMarkProcess()
72+
}
6673
TextUtils.isEmpty(binding.edtXPos.text.toString()) -> {
6774
Toast.makeText(this, getString(R.string.x_position_validation), Toast.LENGTH_SHORT).show()
6875
}
@@ -126,12 +133,26 @@ class AddWaterMarkOnVideoActivity : BaseActivity(R.layout.activity_add_water_mar
126133
private fun addWaterMarkProcess() {
127134
val outputPath = getFilePath(this, VIDEO)
128135
val xPos = width?.let {
129-
(binding.edtXPos.text.toString().toFloat().times(it)).div(100)
136+
if (binding.edtXPos.text.isEmpty()) null
137+
else
138+
(binding.edtXPos.text?.toString()?.toFloat()?.times(it))?.div(100)
130139
}
131140
val yPos = height?.let {
132-
(binding.edtYPos.text.toString().toFloat().times(it)).div(100)
141+
if (binding.edtYPos.text.isEmpty()) null
142+
else
143+
(binding.edtYPos.text?.toString()?.toFloat()?.times(it))?.div(100)
133144
}
134-
val query = ffmpegQueryExtension.addVideoWaterMark(binding.tvInputPathVideo.text.toString(), binding.tvInputPathImage.text.toString(), xPos, yPos, outputPath)
145+
146+
val selectedPosition = binding.spinner.selectedItem.toString()
147+
148+
val query = ffmpegQueryExtension.addVideoWaterMark(
149+
binding.tvInputPathVideo.text.toString(),
150+
binding.tvInputPathImage.text.toString(),
151+
position = if (selectedPosition == "custom") null else selectedPosition,
152+
posX = if (selectedPosition == "custom") xPos else null,
153+
posY = if (selectedPosition == "custom") yPos else null,
154+
output = outputPath
155+
)
135156
CallBackOfQuery().callQuery(query, object : FFmpegCallBack {
136157
override fun process(logMessage: LogMessage) {
137158
binding.tvOutputPath.text = logMessage.text
@@ -169,4 +190,18 @@ class AddWaterMarkOnVideoActivity : BaseActivity(R.layout.activity_add_water_mar
169190
mProgressView.root.visibility = View.VISIBLE
170191
}
171192
}
193+
194+
private fun setUpSpinner() {
195+
val positionOptions = listOf(
196+
"custom", // for x/y coordinates
197+
"center",
198+
"fill",
199+
"crop",
200+
"top-left",
201+
"top-right",
202+
"bottom-left",
203+
"bottom-right"
204+
)
205+
binding.spinner.adapter = ArrayAdapter(this, android.R.layout.simple_spinner_item, positionOptions)
206+
}
172207
}

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)