[Huawei Developers] Sherlock F:
More information like this, you can visit HUAWEI Developer Forum​

Intoduction:

HUAWEI Video Kit provides an excellent playback experience with video streaming from a third-party cloud platform. It supports streaming media in 3GP, MP4, or TS format and comply with HTTP/HTTPS, HLS, or DASH.

Advantage of Video Kit:

Provides an excellent video experience with no lag, no delay, and high definition.

Provides a complete and rich playback control interfaces.

Provides rich video operation experience.

Prerequisites:

Android Studio 3.X

JDK 1.8 or later

HMS Core (APK) 5.0.0.300 or later

EMUI 3.0 or later

Integration:

1. Create an project in android studio and Huawei AGC.

2. Provide the SHA-256 Key in App Information Section.

3. Download the agconnect-services.json from AGCand save into app directory.

4. In root build.gradle

Navigate to allprojects > repositories and buildscript > repositories and add the given line.

maven { url 'http://developer.huawei.com/repo/' }

In dependency add class path.

classpath 'com.huawei.agconnect:agcp:1.3.1.300'

5. In app build.gradle

Configure the Maven dependency

implementation "com.huawei.hms:videokit-player:1.0.1.300"

Configure the NDK

android {
defaultConfig {
......
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
}
......
}

Apply plugin

apply plugin: 'com.huawei.agconnect'

6. Permissions in Manifest

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.huawei.permission.SECURITY_DIAGNOSE" />

Code Implementation:

A movie promo application has been created to demonstrate HMS Video Kit . The application uses recycleview, cardview and piccaso libraries apart from HMS Video Kit library. Let us go to the details of HMS Video kit code integration.

1. Initializing WisePlayer

We have to implement a class that inherits Application and the onCreate() method has to call the initialization API WisePlayerFactory.initFactory()

public class VideoKitPlayApplication extends Application {
private static final String TAG = VideoKitPlayApplication.class.getSimpleName();
private static WisePlayerFactory wisePlayerFactory = null;
@Override
public void onCreate() {
super.onCreate();
initPlayer();
}
private void initPlayer() {
// DeviceId test is used in the demo.
WisePlayerFactoryOptions factoryOptions = new WisePlayerFactoryOptions.Builder().setDeviceId("xxx").build();
WisePlayerFactory.initFactory(this, factoryOptions, initFactoryCallback);
}
/**
* Player initialization callback
*/
private static InitFactoryCallback initFactoryCallback = new InitFactoryCallback() {
@Override
public void onSuccess(WisePlayerFactory wisePlayerFactory) {
LogUtil.i(TAG, "init player factory success");
setWisePlayerFactory(wisePlayerFactory);
}
@Override
public void onFailure(int errorCode, String reason) {
LogUtil.w(TAG, "init player factory failed :" + reason + ", errorCode is " + errorCode);
}
};
/**
* Get WisePlayer Factory
*
* @return WisePlayer Factory
*/
public static WisePlayerFactory getWisePlayerFactory() {
return wisePlayerFactory;
}
private static void setWisePlayerFactory(WisePlayerFactory wisePlayerFactory) {
VideoKitPlayApplication.wisePlayerFactory = wisePlayerFactory;
}
}

2. Creating instance of wise player

wisePlayer = VideoKitPlayApplication.getWisePlayerFactory().createWisePlayer();

3. Initialize the WisePlayer layout and add layout listeners

private void initView(View view) {
if (view != null) {
surfaceView = (SurfaceView) view.findViewById(R.id.surface_view);
textureView = (TextureView) view.findViewById(R.id.texture_view);
if (PlayControlUtil.isSurfaceView()) {
//SurfaceView display interface
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(thois);
textureView.setVisibility(View.GONE);
surfaceView.setVisibility(View.VISIBLE);
} else {
//TextureView display interface
textureView.setSurfaceTextureListener(this);
textureView.setVisibility(View.VISIBLE);
surfaceView.setVisibility(View.GONE);
}
}

4. Register WisePlayer listeners

private void setPlayListener() {
if (wisePlayer != null) {
wisePlayer.setErrorListener(onWisePlayerListener);
wisePlayer.setEventListener(onWisePlayerListener);
wisePlayer.setResolutionUpdatedListener(onWisePlayerListener);
wisePlayer.setReadyListener(onWisePlayerListener);
wisePlayer.setLoadingListener(onWisePlayerListener);
wisePlayer.setPlayEndListener(onWisePlayerListener);
wisePlayer.setSeekEndListener(onWisePlayerListener);
}
}

5. Set playback parameters

player.setVideoType(PlayMode.PLAY_MODE_NORMAL);
player.setBookmark(10000);
player.setCycleMode(CycleMode.MODE_CYCLE);

6. Set URL for video

wisePlayer.setPlayUrl(new String[] {currentPlayData.getUrl()});

7. Set a view to display the video.

// SurfaceView listener callback
@Override
public void surfaceCreated(SurfaceHolder holder) {
wisePlayer.setView(surfaceView);
}
// TextureView listener callback
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
wisePlayer.setView(textureView);
// Call the resume API to bring WisePlayer to the foreground.
wisePlayer.resume(ResumeType.KEEP);
}

8. Prepare for the playback and start requesting data.

wisePlayer.ready();

9. Start the playback upon a success response of the onReady callback method

@Override
public void onReady(WisePlayer wisePlayer) {
player.start();
}

10. select_play_movie.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:tag="cards main container">

<androidx.cardview.widget.CardView
android:id="@+id/card_view"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardBackgroundColor="@color/colorbg"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="5dp"
card_view:cardUseCompatPadding="true">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
>

<ImageView
android:id="@+id/videoIcon"
android:tag="image_tag"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_margin="5dp"
android:layout_weight="1"
android:src="@drawable/j1"/>

<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_weight="2"
android:orientation="vertical"
>

<TextView
android:id="@+id/play_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:text="Jurassic Park"
android:textColor="@color/colorTitle"
android:textAppearance="?android:attr/textAppearanceLarge"/>

<TextView
android:id="@+id/releasedYear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:textColor="@color/black"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="@+id/briefStory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="10dp"
android:textColor="@color/green"
android:textAppearance="?android:attr/textAppearanceSmall"/>
<TextView
android:id="@+id/play_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="@color/select_play_text_color"
android:textSize="20sp"
android:visibility="gone"/>

<TextView
android:id="@+id/play_url"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:marqueeRepeatLimit="marquee_forever"
android:maxLines="2"
android:paddingTop="5dip"
android:singleLine="false"
android:textColor="@color/select_play_text_color"
android:textSize="14sp"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>

</androidx.cardview.widget.CardView>

</LinearLayout>

11.SelectMoviePlayAdapter.java

/**
* Play recyclerView adapter
*/
public class SelectMoviePlayAdapter extends RecyclerView.Adapter<SelectMoviePlayAdapter.PlayViewHolder> {
private static final String TAG = "SelectMoviePlayAdapter ";

// Data sources list
private List<MovieEntity> playList;

// Context
private Context context;

// Click item listener
private OnItemClickListener onItemClickListener;

/**
* Constructor
*
* @param context Context
* @param onItemClickListener Listener
*/
public SelectMoviePlayAdapter(Context context, OnItemClickListener onItemClickListener) {
this.context = context;
playList = new ArrayList<>();
this.onItemClickListener = onItemClickListener;
}

/**
* Set list data
*
* @param playList Play data
*/
public void setSelectPlayList(List<MovieEntity> playList) {
if (this.playList.size() > 0) {
this.playList.clear();
}
this.playList.addAll(playList);
notifyDataSetChanged();
}

@NonNull
@Override
public PlayViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.select_play_movie, parent, false);
return new PlayViewHolder(view);
}
@Override
public void onBindViewHolder(PlayViewHolder holder, final int position) {
if (playList.size() > position && holder != null) {
MovieEntitymovieEntity = playList.get(position);
if (movieEntity== null) {
LogUtil.i(TAG, "current item data is empty.");
return;
}
holder.playName.setText(movieEntity.getName());
holder.releasedYear.setText(movieEntity.getYear());
holder.briefStory.setText(movieEntity.getStory());
holder.playUrl.setText(movieEntity.getUrl());
holder.playType.setText(String.valueOf(movieEntity.getUrlType()));
holder.itemView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
onItemClickListener.onItemClick(position);
}
});

Picasso.with(context).load(movieEntity.getIcon()).into(holder.videoIcon);
}
}

@Override
public int getItemCount() {
return playList.size();
}

/**
* Show view holder
*/
static class PlayViewHolder extends RecyclerView.ViewHolder {

private TextView playName;
private TextView releasedYear,briefStory;
private TextView playType;
private TextView playUrl;
private ImageView videoIcon;

/**
* Constructor
*
* @param itemView Item view
*/
public PlayViewHolder(View itemView) {
super(itemView);
if (itemView != null) {
playName = itemView.findViewById(R.id.play_name);
releasedYear = itemView.findViewById(R.id.releasedYear);
briefStory = itemView.findViewById(R.id.briefStory);
playType = itemView.findViewById(R.id.play_type);
playUrl = itemView.findViewById(R.id.play_url);
videoIcon = itemView.findViewById(R.id.videoIcon);
}
}
}
}

ScreenShots:

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/745/226/2640091000001745226.20200909064233.72214783617162253927988157039343:50510922030025:2800:0D8EE0C9B9A3068BE8759242543B9A630C58CE50326C71027CF4B4865C6246E4.jpg"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/745/226/2640091000001745226.20200909064233.72214783617162253927988157039343:50510922030025:2800:0D8EE0C9B9A3068BE8759242543B9A630C58CE50326C71027CF4B4865C6246E4.jpg[/IMG]

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/745/226/2640091000001745226.20200909064307.59691424578282155593323499815255:50510922030025:2800:A62682B38E5288E3D41102284BAF16401B899168DC1D79FB84F9ADD7A57DB778.jpg"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/001/745/226/2640091000001745226.20200909064307.59691424578282155593323499815255:50510922030025:2800:A62682B38E5288E3D41102284BAF16401B899168DC1D79FB84F9ADD7A57DB778.jpg[/IMG]

Conclusion:

Video Kit provides an excellent experience in video playback. In future it will support video editing and video hosting, through that users can easily and quickly enjoy an end-to-end video solution for all scenarios

Reference:

https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides-V5/introduction-0000001050439577-V5