[Huawei Developers] Onur OKYAY:
HMS Video Kit — 2

In this article, we are going to use some of the other important features of the video kit.

Settings Dialog

With this dialog, users will be able to change the playback options of the video. When the user clicks on TextView which is called Settings, the options will pop up through alert dialog.

Settings

First of all, I will shortly explain how we get the click actions on one of the settings clicked and then I will explain them all separately.

For the settings dialog, we create DialogUtil.java and PlaySettingDialog.java class that implements DialogInterface.OnClickListener. In its initDialog method, we get the playSettingType and OnPlaysettingListener interface and assign them to their local instance variables.

public PlaySettingDialog initDialog(OnPlaySettingListener playSettingListener, int playSettingType) {
this.onPlaySettingListener = playSettingListener;
this.playSettingType = playSettingType;
return this;
}

Here, OnPlaySettingListener is an interface that we will get its callback on our PlayActivity.java class to determine the selected item and setting type.

/**
* The player setting listener
*/
public interface OnPlaySettingListener {
/**
* Dialog select listener
*
* @param itemSelect The selected text
* @param settingType The corresponding operation type of player
*/
void onSettingItemClick(String itemSelect, int settingType);
}

When the user clicks on an item from the settings dialog, inside of its OnClick() method, we set the onSettingItemClick and cancel the alert dialog.

@Override
public void onClick(DialogInterface dialog, int which) {
if (onPlaySettingListener != null) {
onPlaySettingListener.onSettingItemClick(showTextList.get(which).first, playSettingType);
}
dialog.dismiss();
}

Now, I would like to go top again to our PlayActivity.java class. As you remember we have a play_view.xml layout file and onClick listener for some of our View components. We call onSettingDialog method when the user clicks on Settings TextView.

@Override
public void onClick(View v) {
switch (v.getId()) {
...
case R.id.setting_tv:
onSettingDialog();
break;
...
}
}

We prepare the text list of our settings dialog and call the showSettingDialog of our playView object. Then it calls the onSettingDialogSelectIndex method of DialogUtil class that will create a new PlaySettingDialog object and prepare it for the user.

/**
* Show the Settings dialog
*/
private void onSettingDialog() {
List<String> showTextList = new ArrayList<>();
showTextList.add(StringUtil.getStringFromResId(this, R.string.video_set_bandwidth_mode));
showTextList.add(StringUtil.getStringFromResId(this, R.string.video_stop_downloading));
showTextList.add(StringUtil.getStringFromResId(this, R.string.video_set_play_speed));
showTextList.add(StringUtil.getStringFromResId(this, R.string.play_mode));
showTextList.add(StringUtil.getStringFromResId(this, R.string.video_set_loop_play));
showTextList.add(StringUtil.getStringFromResId(this, R.string.video_mute_setting));
showTextList.add(StringUtil.getStringFromResId(this, R.string.video_set_volume));
playView.showSettingDialog(Constants.MSG_SETTING, showTextList, 0);
}

Lastly, when the user clicks on one of the items from the settings dialog, we get the itemSelect and settingType values in our PlayActivity’s onSettingItemClick callback thanks to OnPlaySettingListener interface.

@Override
public void onSettingItemClick(String itemSelect, int settingType) {
switch (settingType) {
case Constants.MSG_SETTING:
Log.d(TAG, "onSettingItemClick: MSG_SETTING CASE.");
if (TextUtils.equals(itemSelect,
StringUtil.getStringFromResId(PlayActivity.this, R.string.video_mute_setting))) {
switchVideoMute();
} else if (TextUtils.equals(itemSelect,
StringUtil.getStringFromResId(PlayActivity.this, R.string.video_set_bandwidth_mode))) {
switchBandwidthMode();
} else if (TextUtils.equals(itemSelect,
StringUtil.getStringFromResId(PlayActivity.this, R.string.video_set_play_speed))) {
setPlaySpeed();
} else if (TextUtils.equals(itemSelect,
StringUtil.getStringFromResId(PlayActivity.this, R.string.video_stop_downloading))) {
stopRequestStream();
} else if (TextUtils.equals(itemSelect,
StringUtil.getStringFromResId(PlayActivity.this, R.string.video_set_volume))) {
setVideoVolume();
} else if (TextUtils.equals(itemSelect,
StringUtil.getStringFromResId(PlayActivity.this, R.string.play_mode))) {
switchPlayMode();
} else if (TextUtils.equals(itemSelect,
StringUtil.getStringFromResId(PlayActivity.this, R.string.video_set_loop_play))) {
switchPlayLoop();
} else {
LogUtil.i(TAG, "current settings type is " + itemSelect);
}
break;
case Constants.PLAYER_SWITCH_PLAY_SPEED:
onSwitchPlaySpeed(itemSelect);
break;
case Constants.PLAYER_SWITCH_BANDWIDTH_MODE:
if (TextUtils.equals(itemSelect,
StringUtil.getStringFromResId(PlayActivity.this, R.string.open_adaptive_bandwidth))) {
playControl.setBandwidthSwitchMode(PlayerConstants.BandwidthSwitchMode.AUTO_SWITCH_MODE, true);
} else {
playControl.setBandwidthSwitchMode(PlayerConstants.BandwidthSwitchMode.MANUAL_SWITCH_MODE, true);
}
break;
...
}
}

I explained how the settings dialog works. You can also refer to my demo code for a better understanding. From now on, I will keep going with the features of the video kit.

Bandwidth Adaptation

It allows you to dynamically adapt the bitrate of the stream to varying network conditions and selects the most suitable bitrate for your app. Adaptive bitrate streaming works by detecting a user’s bandwidth and CPU capacity in real-time and adjusting the quality of the media stream accordingly. When the user clicks on Bandwidth adaptation we call the switchBandwidthMode() method.

/**
* Set the bandwidth switch
*/
private void switchBandwidthMode() {
List<String> showTextList = new ArrayList<>();
showTextList.add(getResources().getString(R.string.close_adaptive_bandwidth));
showTextList.add(getResources().getString(R.string.open_adaptive_bandwidth));
playView.showSettingDialog(Constants.PLAYER_SWITCH_BANDWIDTH_MODE, showTextList, Constants.DIALOG_INDEX_ONE);
}

When the user makes the choice, again we get it in onSettingItemClick callback of PlayActivity class.

@Override
public void onSettingItemClick(String itemSelect, int settingType) {
switch (settingType) {
...
case Constants.PLAYER_SWITCH_BANDWIDTH_MODE:
if (TextUtils.equals(itemSelect,
StringUtil.getStringFromResId(PlayActivity.this, R.string.open_adaptive_bandwidth))) {
playControl.setBandwidthSwitchMode(PlayerConstants.BandwidthSwitchMode.AUTO_SWITCH_MODE, true);
} else {
playControl.setBandwidthSwitchMode(PlayerConstants.BandwidthSwitchMode.MANUAL_SWITCH_MODE, true);
}
break;
...
}
}

Our playControl object’s setBandwidthSwitchMode() method will be called.

/**
* Set the bandwidth switching mode
*
* @param mod The bandwidth switching mode
* @param updateLocate Whether to update the local configuration
*/
public void setBandwidthSwitchMode(int mod, boolean updateLocate) {
if (wisePlayer != null) {
wisePlayer.setBandwidthSwitchMode(mod);
}
if (updateLocate) {
PlayControlUtil.setBandwidthSwitchMode(mod);
}
}

Here wisePlayer.setBandwidthSwitchMode() sets whether to enable adaptive bitrate streaming or keep using the current bitrate.

Download Control

This feature allows us to stop buffering if required. For instance, if you are watching a video on a mobile network and pause it, you can stop video buffering.

/**
* Whether to stop the downloading
*
* @param selectValue Select text value
*/
private void onSwitchRequestMode(String selectValue) {
if (selectValue.equals(StringUtil.getStringFromResId(PlayActivity.this, R.string.video_keep_download))) {
streamRequestMode = 0;
} else if (selectValue.equals(StringUtil.getStringFromResId(PlayActivity.this, R.string.video_stop_download))) {
streamRequestMode = 1;
}
LogUtil.i(TAG, "mStreamRequestMode:" + streamRequestMode);

playControl.setBufferingStatus(streamRequestMode == 0 ? true : false, true);
}

Here, for demonstration, if the user selects the stop download option, wisePlayer.setBufferingStatus() method will be called and the video buffering will stop.

public void setBufferingStatus(boolean status, boolean isUpdateLocal) {
if (wisePlayer != null && (isUpdateLocal || PlayControlUtil.isLoadBuff())) {
wisePlayer.setBufferingStatus(status);
if (isUpdateLocal) {
PlayControlUtil.setLoadBuff(status);
}
}
}

Playback Speed

Wiseplayer video kit allows us to change playback speed with setPlaySpeed() method call. In the demo project, I put that option to both settings dialog and the play speed button in activity_play.xml.

/**
* Set the speed
*
* @param speedValue The speed of the string
*/
public void setPlaySpeed(String speedValue) {
if (speedValue.equals("1.25x")) {
wisePlayer.setPlaySpeed(1.25f);
} else if (speedValue.equals("2.0x")) {
wisePlayer.setPlaySpeed(2.0f);
}
...
else {
wisePlayer.setPlaySpeed(1.0f);
}
}

Playback Mode

With this feature, we can set the playback mode to audio-only or audio+video.

/**
* Set play mode
*
* @param playMode Play mode
* @param updateLocate Whether to update the local configuration
*/
public void setPlayMode(int playMode, boolean updateLocate) {
if (wisePlayer != null) {
wisePlayer.setPlayMode(playMode);
}
if (updateLocate) {
PlayControlUtil.setPlayMode(playMode);
}
}

Repeat Mode

If we enable the repeat mode, after playing a video is finished, WisePlayer will not call PlayEndListener. Instead, it will play the video again from the beginning of it. To achieve it, we call the setCycleMode() method of the API.

/**
* Set cycle mode
*
* @param isCycleMode Whether open loop
*/
public void setCycleMode(boolean isCycleMode) {
if (wisePlayer != null) {
wisePlayer.setCycleMode(isCycleMode ? PlayerConstants.CycleMode.MODE_CYCLE : PlayerConstants.CycleMode.MODE_NORMAL);
}
}

Mute/Unmute

We can use the setMute(boolean status) method in order to indicate whether to mute a video or not.

/**
* Set the mute
*
* @param status Whether quiet
*/
public void setMute(boolean status) {
if (wisePlayer != null) {
wisePlayer.setMute(status);
}
PlayControlUtil.setIsMute(status);
}

Volume

We can set the playback volume by using the setVolume() method. The value ranges from 0 to 1.0. In the demo app, I have used a volume button in the activity_play.xml. We can set the volume either selecting it from the settings dialog or clicking on the volume button. I also used a seek bar for setting the desired volume level easily.

/**
* Set the volume, the current player is interval [0, 1]
*
* @param volume The volume interval [0, 1]
*/
public void setVolume(float volume) {
if (wisePlayer != null) {
LogUtil.d(TAG, "current set volume is " + volume);
wisePlayer.setVolume(volume);
}
}

In order to control the volume through the seek bar, we can add the code below.

public static void showSetVolumeDialog(Context context,
final OnDialogInputValueListener onDialogInputValueListener) {
View view = LayoutInflater.from(context).inflate(R.layout.set_volume_dialog, null);
final AlertDialog dialog =
new AlertDialog.Builder(context).setTitle(StringUtil.getStringFromResId(context, R.string.video_set_volume))
.setView(view)
.create();
dialog.show();
final SeekBar volumeSeek = (SeekBar) view.findViewById(R.id.seek_bar_volume);
volumeSeek.setProgress(0);
volumeSeek.setMax(100);
volumeSeek.setProgress(last_state);
volumeSeek.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
float progress_f;
progress_f = (float) progress / 100;
onDialogInputValueListener.dialogInputListener(Float.toString(progress_f));
last_state = progress;
}
...
}

You can find the source code of the demo app here.

In this article, we have used some of the important features of the video kit. HUAWEI Video Kit will support video editing and video hosting in later versions. Once the new features are released, I will be sharing a demo application that implements them.

For more information and features about the Video Kit, you can refer to the sources below.

RESOURCES

About the Service

API Reference