Detecting Video Playback Progress in Android Using UiAutomator and Bitmap Analysis
This article demonstrates how to capture a video progress bar in an Android app with UiAutomator, extract its bitmap, analyze the red channel values, and compute the playback percentage for automated test assertions.
When testing an Android application with UiAutomator, the author needed to verify video playback progress by analyzing the progress bar’s color (red) and calculating the percentage.
First, a screenshot of the progress bar is captured, and the relevant UI element is cropped to a Bitmap using getBitmapByResourceId . The method obtains the element’s Rect , takes a screenshot, decodes the file, and creates a bitmap of the specified bounds.
Then getVideoProgress scans the bitmap horizontally, records the red channel values, and identifies key color thresholds (255, 238, 165) to locate the start, filled, and end positions of the progress bar. The percentage is computed with the formula (date2 + date3 - date1 * 2.00) / (date4 - date1) / 2 .
The main test case clicks the video area, waits, captures the bitmap, calls getVideoProgress , and obtains the progress value for assertion.
Code example:
package student;
import java.io.IOException;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import com.android.uiautomator.core.UiObjectNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.RemoteException;
import source.UiAutomatorHelper;
/**
* @author ..-·尘
* @E-mail:[email protected]
* @version 创建时间:2017年8月18日 上午10:53:24
* @alter 修改时间:2017年9月7日 12:55:36
* 类说明:测试调试用例
*/
@SuppressWarnings("deprecation")
public class Student extends StudentCase {
public static String jarName,testClass,testName,androidId;
public static void main(String[] args) throws ClassNotFoundException, SQLException, InterruptedException, IOException, ParseException {
jarName = "DemoStudent";testClass="student.Student";testName="testTest";
new UiAutomatorHelper(jarName, testClass, testName);
}
public void testTest() throws InterruptedException, IOException, UiObjectNotFoundException, RemoteException {
clickPiont(500, 500); // click to show progress bar
sleep(100);
Bitmap bitmap = getBitmapByResourceId("com.genshuixue.student:id/view_video_coursede_control_seekbar");
double percent = getVideoProgress(bitmap);
}
} public Bitmap getBitmapByResourceId(String id) throws UiObjectNotFoundException {
Rect rect = getUiObjectByResourceId(id).getVisibleBounds(); // get control bounds
String path = screenShot("test"); // take screenshot
Bitmap bitmap = BitmapFactory.decodeFile(path); // decode file
bitmap = Bitmap.createBitmap(bitmap, rect.left, rect.top, rect.width(), rect.height()); // crop
return bitmap;
} public double getVideoProgress(Bitmap bitmap) {
int height = bitmap.getHeight();
int width = bitmap.getWidth();
List
data = new ArrayList
();
for (int i = 0; i < width; i++) {
int color = bitmap.getPixel(i, height / 2);
int red = Color.red(color);
data.add(red);
}
int date1 = 0, date2 = 0, date3 = 0, date4 = 0;
int status1 = 0, status2 = 0;
for (int i = 1; i < data.size() - 1; i++) {
if (data.get(i) == 255 && status1 == 0) { status1++; date1 = i; }
if (data.get(i) == 238 && status2 == 0) { status2++; date2 = i; }
if (data.get(i + 1) < 238 && data.get(i) == 238) { date3 = i; }
if (data.get(i + 1) < 165 && data.get(i) == 165) { date4 = i; }
}
return (date2 + date3 - date1 * 2.00) / (date4 - date1) / 2;
}FunTester
10k followers, 1k articles | completely useless
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.