Getting Started with the Intel Media SDK

本文介绍了Intel MediaSDK的基本安装配置及使用教程,包括所需的操作系统、支持的处理器类型、媒体处理功能如视频编码解码等,并提供了多个示例项目来帮助开发者快速上手。
Follow Gael on Twitter: @GaelHof

One thing that developers might find a little confusing is that a search for the Intel® Media SDK takes you to an Intel® Integrated Native Developer Experience (Intel® INDE) download page.  This is because the Intel Media SDK is now a feature included in the Intel INDE tools suite.

DownloadINDE

If all you need is the Intel Media SDK then you must select the “Get Intel® INDE” option on the download page. See Quick Installation Guide for Media SDK on Windows with Intel® INDE for complete instructions on how to download a standalone version of the Intel Media SDK.


Media applications target both CPUs and GPUs.  Here are the specifications for the Intel Media SDK 2014:

Video EncodersH.264 (AVC and MVC), MPEG-2, JPEG*/Motion JPEG, HEVC(SW)
Video DecodersH.264 (AVC and MVC), MPEG-2, VC-1, JPEG*/Motion JPEG, HEVC(SW)
Video Processing FiltersDeinterlacing/Inverse Telecine, Resizing, Color Conversion, Denoising, Frame Rate Conversion, Brightness, Contrast, Hue, Saturation Control, Sharpening, Image Stabilization
Video ConferencingDynamic bitrate control, Low Latency, Error Detection/Resilience, temporal scalability, dynamic resolution change, long term reference frames, Rolling I-Frame
ExtensionsUser-defined filters (HEVC encoder/decoder delivered as plug-ins)Example plug-ins for OpenCL and VP8 decode.

Accelerated Video Operations: The Intel Media SDK contains optimized media libraries that are built on top of Microsoft Direct*, DirectX Video Acceleration (DVXA) APIs, and platform graphics drivers. The Intel Media SDK also exposes the hardware acceleration features of Intel® Quick Sync Video built into 2nd, 3rd, and 4th generation Intel® Core™ processors.

The Intel Media SDK focuses on media pipeline components that are most commonly used and in need of acceleration, such as:

  • Decoding from video elementary stream formats (H.264, MPEG-2, VC-1, and JPEG*/Motion JPEG, new: HEVC) to uncompressed frames
  • Selected video frame processing operations
  • Encoding uncompressed frames to elementary stream formats (H.264, MPEG-2, new: HEVC)
  • New: Audio encode/decode and container split/muxing

Here is an example of a generic transcode pipeline. The Intel Media SDK accelerates a subset of the most computationally demanding video elementary streaming tasks.MediaSDKFlow

Install the Graphics Driver and the Intel Media SDK

In order to take full advantage of the Media SDK’s capabilities, you will need to install both the graphics driver and the Intel Media SDK. The Graphics Driver and the Media SDK are distributed in two separate downloads.  The Media SDK can be installed before or after the driver and the driver can be updated without re-installing the Media SDK.  Note, however, that hardware acceleration is available only if both components are installed successfully. The media acceleration DLLs are distributed with the graphics driver, not the Intel Media SDK.  The default graphics driver may or may not provide all of the files and registry components necessary.  The link for the Intel Graphics Drivers is included above.  When downloaded, the graphics installer will populate the Media SDK directories located here:  <root>\Program Files\Intel\Media SDK

GraphicsMediaSDK

Structure of the Intel Media SDK:

Unless otherwise specified, the Media SDK is saved to the following folder on your computer:

  • <root>\Intel\INDE\media_sdk_6.0.0.308

Here is the basic file structure:

FileStructure

Using the Intel Media SDK Samples

The Samples projects were created for Microsoft Visual Studio 2005.  If you are using a more recent version, you will encounter a warning – this is not a problem.

The samples provided in the SDK demonstrate how to utilize the library without the additional complexity of a GUI or media framework.  The samples are very basic and are provided as a starting point for developers. The major components of the SDK are represented by  basic console applications as described below:

 Basic Samples:

Sample_decodeDecoding from an elementary stream to raw (uncompressed) frames. Includes decoding of an elementary MVC video stream and use of the Stereoscopic 3D (S3D) API.
sample_encodeEncoding from raw frames to a compressed (elementary) stream.
sample_multi_transcodeTranscoding to and from elementary stream(s). Illustrates multiple asynchronous sessions to perform batch processing.
sample_vppAn example of how to use pixel preprocessing to manipulate raw (uncompressed) frames

Advanced Samples

sample_full_transcodeShowcases a complete transcoding pipeline, including audio decode/encode and container splitting and muxing
sample_user_modulesOpenCL™, VP8 decode user plugins.
sample_utilitiesPipeline construction combining VPP and user plugins.
sample_videoconfLow latency, packet loss, dynamic bitrate, key frame insertion, long-term reference frame generation.

The SDK also contains Microsft DirectShow filter samples, as well as Windows-based GUI applications (DirectShow Player and MediaFoundation TranscodeSample).

You can watch the Intel Media SDK Tutorials that will take you through 7 distinct sections with increasing levels of complexity:

  • Section 1: Introduces the Intel Media SDK session concept via a very simple sample.
  • Section 2-4: Illustrates how to utilize the three core SDK components: Decode, Encode, and VPP.
  • Section 5: Showcases transcode workloads, utilizing the components described in earlier sections.
  • Section 6: Describes more advanced and compound usages of the SDK.
  • Section 7: Explains how to integrate OpenCL processing into the Intel Media SDK pipelines.

Ok, this should get you started.  For further information, here are some great resources:

Gael Hofemeier

About Gael Hofemeier

Technology Evangelista/Intel Black Belt always learning. Live and play in the Portland, Oregon area.

Categories: Application Innovation, Intel, Intel Software   |   Tagged as: acceleration, Drivers, GPU, Graphics, Media SDK

Bookmark the permalink.

2 Responses to Getting Started with the Intel Media SDK

    1. Walter An says:
      April 11, 2015 at 2:26 AM

      Hi,
      Is there a place in Intel web site where the list of supported Intel CPUs that can run Intel Media SDK Client for Windows?
      Actually I want to know whether Intel® Xeon® Processor E3-1285 v3 can run Intel Media SDK Client for Windows or not.
      Thank you.

       
    2. April 15, 2015 at 9:00 PM

      Hi Walter,
      I apologize for the delay: According to the Release Notes, the E3-1285 v3 is compatible.

      Hardware
      The following processor models are supported:
       Intel® Xeon® Processor E3-128x v3 with Intel C226 Chipset:
      Intel® Xeon® Processor E3-1284 v3
      Intel® Xeon® Processor E3-1285 v3
      Intel® Xeon® Processor E3-1285L v3
      Intel® Xeon® Processor E3-1286 v3
      Intel® Xeon® Processor E3-1286L v3

      https://software.intel.com/sites/default/files/managed/64/01/media_server_studio_essentials_release_notes_linux.pdf

转载于:https://www.cnblogs.com/gune/p/6488781.html

logcat:2025-06-23 15:10:40.037 1491-3220 ActivityTrigger system_server E activityStartTrigger: not whiteListedcom.hik.netsdk.SimpleDemo/com.hik.netsdk.SimpleDemo.View.MainActivity/11 2025-06-23 15:10:40.038 1491-3220 ActivityTrigger system_server E activityResumeTrigger: not whiteListedcom.hik.netsdk.SimpleDemo/com.hik.netsdk.SimpleDemo.View.MainActivity/11 2025-06-23 15:10:40.044 1491-3220 ActivityTrigger system_server E activityResumeTrigger: not whiteListedcom.hik.netsdk.SimpleDemo/com.hik.netsdk.SimpleDemo.View.MainActivity/11 ---------------------------- PROCESS STARTED (15498) for package com.hik.netsdk.SimpleDemo ---------------------------- 2025-06-23 15:10:40.330 15498-15498 ResourceType com.hik.netsdk.SimpleDemo W No package identifier when getting name for resource number 0x00000000 2025-06-23 15:10:40.366 15498-15498 ResourceType com.hik.netsdk.SimpleDemo W No package identifier when getting name for resource number 0x00000000 2025-06-23 15:10:40.399 15498-15498 NetworkSecurityConfig com.hik.netsdk.SimpleDemo D No Network Security Config specified, using platform default 2025-06-23 15:10:40.406 15498-15498 ResourceType com.hik.netsdk.SimpleDemo W No package identifier when getting name for resource number 0x00000000 2025-06-23 15:10:40.412 15498-15498 ResourceType com.hik.netsdk.SimpleDemo W No package identifier when getting name for resource number 0x00000000 2025-06-23 15:10:40.446 15498-15533 ResourceType com.hik.netsdk.SimpleDemo W No package identifier when getting name for resource number 0x00000000 2025-06-23 15:10:40.450 15498-15498 AccessibilityManager com.hik.netsdk.SimpleDemo D AccessibilityManager status: mPackageName = com.hik.netsdk.SimpleDemo, mOptimizeEnabled = true, mIsEnabled = false, mIsUiAutomationEnabled = false, mIsInterestedPackage =false 2025-06-23 15:10:40.461 15498-15533 ViewContentFactory com.hik.netsdk.SimpleDemo D initViewContentFetcherClass 2025-06-23 15:10:40.461 15498-15533 ViewContentFactory com.hik.netsdk.SimpleDemo D getInterceptorPackageInfo 2025-06-23 15:10:40.462 15498-15533 ViewContentFactory com.hik.netsdk.SimpleDemo D getInitialApplication took 1ms 2025-06-23 15:10:40.462 15498-15533 ViewContentFactory com.hik.netsdk.SimpleDemo D packageInfo.packageName: com.miui.catcherpatch 2025-06-23 15:10:40.464 15498-15533 ResourceType com.hik.netsdk.SimpleDemo W No package identifier when getting name for resource number 0x00000000 2025-06-23 15:10:40.471 15498-15503 zygote64 com.hik.netsdk.SimpleDemo I Do partial code cache collection, code=30KB, data=19KB 2025-06-23 15:10:40.471 15498-15503 zygote64 com.hik.netsdk.SimpleDemo I After code cache collection, code=30KB, data=19KB 2025-06-23 15:10:40.471 15498-15503 zygote64 com.hik.netsdk.SimpleDemo I Increasing code cache capacity to 128KB 2025-06-23 15:10:40.477 15498-15533 ViewContentFactory com.hik.netsdk.SimpleDemo D initViewContentFetcherClass took 16ms 2025-06-23 15:10:40.477 15498-15533 ContentCatcher com.hik.netsdk.SimpleDemo I ViewContentFetcher : ViewContentFetcher 2025-06-23 15:10:40.478 15498-15533 ViewContentFactory com.hik.netsdk.SimpleDemo D createInterceptor took 16ms 2025-06-23 15:10:40.670 15498-15503 zygote64 com.hik.netsdk.SimpleDemo I Do partial code cache collection, code=39KB, data=37KB 2025-06-23 15:10:40.670 15498-15503 zygote64 com.hik.netsdk.SimpleDemo I After code cache collection, code=39KB, data=37KB 2025-06-23 15:10:40.670 15498-15503 zygote64 com.hik.netsdk.SimpleDemo I Increasing code cache capacity to 256KB 2025-06-23 15:10:40.670 15498-15503 zygote64 com.hik.netsdk.SimpleDemo I Compiler allocated 4MB to compile void android.view.View.<init>(android.content.Context, android.util.AttributeSet, int, int) 2025-06-23 15:10:40.772 15498-15498 AndroidRuntime com.hik.netsdk.SimpleDemo D Shutting down VM 2025-06-23 15:10:40.774 15498-15498 AndroidRuntime com.hik.netsdk.SimpleDemo E FATAL EXCEPTION: main Process: com.hik.netsdk.SimpleDemo, PID: 15498 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.hik.netsdk.SimpleDemo/com.hik.netsdk.SimpleDemo.View.MainActivity}: java.lang.ClassCastException: androidx.appcompat.widget.AppCompatTextView cannot be cast to androidx.appcompat.widget.Toolbar at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2931) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1620) at android.os.Handler.dispatchMessage(Handler.java:105) at android.os.Looper.loop(Looper.java:173) at android.app.ActivityThread.main(ActivityThread.java:6698) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782) Caused by: java.lang.ClassCastException: androidx.appcompat.widget.AppCompatTextView cannot be cast to androidx.appcompat.widget.Toolbar at com.hik.netsdk.SimpleDemo.View.MainActivity.initUIComponents(MainActivity.java:137) at com.hik.netsdk.SimpleDemo.View.MainActivity.onCreate(MainActivity.java:117) at android.app.Activity.performCreate(Activity.java:7040) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2809) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2931)  at android.app.ActivityThread.-wrap11(Unknown Source:0)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1620)  at android.os.Handler.dispatchMessage(Handler.java:105)  at android.os.Looper.loop(Looper.java:173)  at android.app.ActivityThread.main(ActivityThread.java:6698)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)  2025-06-23 15:10:40.804 15498-15498 Process com.hik.netsdk.SimpleDemo I Sending signal. PID: 15498 SIG: 9 依据上述logcat日志解决在VideoListActivity中实现通过用户在设备列表选择Videolist播放通道后传递参数跨应用ysy1.apk中实现已经云接入萤石开放平台的75台摄像头实现实时预览(即摄像头实时监控,现在只需要实现最基础的实时预览)的功能 VideoListActivity:package com.jd.projects.wlw.video; import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.AssetManager; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.support.v4.content.FileProvider; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Button; import android.widget.ListView; import android.widget.Toast; import com.jd.projects.wlw.DeviceMapActivity; import com.jd.projects.wlw.R; import com.jd.projects.wlw.adapter.VideoDevAdapter; import com.jd.projects.wlw.dialog.CreateLoadingDialog; import com.jd.projects.wlw.hkdemo.HkMainActivity; import com.jd.projects.wlw.units.FileUtils; import com.jd.projects.wlw.units.NetHelper; import com.jd.projects.wlw.xmvideo.DahuaVideoActicity; import org.json.JSONObject; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class VideoListActivity extends Activity { private ArrayList<Map<String, String>> mvideolist; private Context context; public static Map<String, String> map; public Button curve3; private String aliasname = "";//站点别名 public static final String package_name = "com.hik.netsdk.SimpleDemo"; public static final String package_name2 = "com.example.funsdkdemo"; public static final String APK_NAME = "ysy1.apk"; public static final String APK_NAME2 = "zxcv.apk"; private int curersioncode = 11;//萤石云插件apk最新版本号。 private int curersioncode2 = 5;//雄迈插件apk最新版本号。 //private String Appkey = "05381ff665c843c398a0a3b6d6e341ac"; private String Appkey = ""; private String devserial = ""; private String VerifyCode = ""; private int channelName = 1; private String accessToken = ""; Map<String, String> mmap; private String response = ""; private CreateLoadingDialog loadingDialg = new CreateLoadingDialog(); private String user_control_power, site_control_power; private String netmode = ""; private String xmip = ""; private String xmport = ""; private String xmusername = ""; private String xmpassword = ""; private String devSn = ""; private String xmmark = ""; private double intentLat = 0.0; private double intentLng = 0.0; @SuppressLint("HandlerLeak") Handler mHandler = new Handler() { public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0: loadingDialg.dismissLoadingDialog(); System.out.println("--访问令牌接口返回--" + response); try { JSONObject object = new JSONObject(response); String code = object.get("code").toString(); String mmsg = object.get("msg").toString(); if (code.equals("200")) { JSONObject object2 = (JSONObject) object.get("data"); accessToken = object2.get("accessToken").toString(); System.out.println("--访问令牌为:--" + accessToken); openAPK(); } else { Toast.makeText(context, mmsg, Toast.LENGTH_SHORT).show(); } } catch (Exception e) { // TODO: handle exception } break; default: break; } } ; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.avtivity_videolist); intentLat = getIntent().getDoubleExtra("intentLat", 0.0); intentLng = getIntent().getDoubleExtra("intentLng", 0.0); context = this; initData(); initView(); } private void initView() { ListView listView = (ListView) findViewById(R.id.Videolist); curve3 = (Button) findViewById(R.id.curve3); VideoDevAdapter adapter = new VideoDevAdapter(mvideolist, context); listView.setAdapter(adapter); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { map = mvideolist.get(position); String mark = map.get("mark"); if (mark.equals("yiwei")) { SerializableMap myMap = new SerializableMap(); myMap.setMap(map); Bundle bundle = new Bundle(); bundle.putSerializable("map", myMap); bundle.putString("user_control_power", user_control_power); bundle.putString("site_control_power", site_control_power); bundle.putString("netmode", netmode); Intent intent = new Intent(); intent.putExtras(bundle); intent.setClass(getApplicationContext(), YwVideoPlayerActivity.class); startActivity(intent); } else if (mark.equals("haikang")) { // 跳转海康页面 String strIP = map.get("serverUrl").trim(); String nPort = map.get("serverPort").trim(); String strUser = map.get("userName").trim(); String strPsd = map.get("userPwd").trim(); Bundle bundle = new Bundle(); bundle.putString("ip", strIP); bundle.putString("port", nPort); bundle.putString("username", strUser); bundle.putString("password", strPsd); bundle.putString("user_control_power", user_control_power); bundle.putString("site_control_power", site_control_power); bundle.putString("netmode", netmode); Intent intent2 = new Intent(); intent2.putExtras(bundle); intent2.setClass(getApplicationContext(), HkMainActivity.class); startActivity(intent2); } else if (mark.equals("dahua")) { // 跳转大华页面 String strIP = map.get("serverUrl").trim(); String nPort = map.get("serverPort").trim(); String strUser = map.get("userName").trim(); String strPsd = map.get("userPwd").trim(); Bundle bundle = new Bundle(); bundle.putString("ip", strIP); bundle.putString("port", nPort); bundle.putString("username", strUser); bundle.putString("password", strPsd); bundle.putString("user_control_power", user_control_power); bundle.putString("site_control_power", site_control_power); bundle.putString("netmode", netmode); Intent intent2 = new Intent(); intent2.putExtras(bundle); intent2.setClass(getApplicationContext(), DahuaVideoActicity.class); startActivity(intent2); } else if (mark.equals("xiongmai") || mark.equals("4Gxiongmai")) { xmip = map.get("serverUrl").trim(); xmport = map.get("serverPort").trim(); xmusername = map.get("userName").trim(); xmpassword = map.get("userPwd").trim(); devSn = map.get("devSn").trim();//雄迈4G球机序列号 xmmark = mark; openAPK2(); } else if (mark.equals("HK4GIPC01")) { // 海康4G摄像机---公司现在暂无使用 String strIP = map.get("serverUrl");//设备序列号 String strUser = map.get("userName");//设备验证名 String strPsd = map.get("userPwd"); Bundle bundle = new Bundle(); bundle.putString("ip", strIP.trim()); bundle.putString("username", strUser.trim()); bundle.putString("password", strPsd.trim()); Intent intent2 = new Intent(); intent2.putExtras(bundle); intent2.setClass(getApplicationContext(), Hk4GVideoMain.class); startActivity(intent2); } else if (mark.equals("HK4GIPC02")) { // 萤石云平台摄像机 devserial = map.get("serverUrl").trim();// 设备序列号 VerifyCode = map.get("serverPort").trim();// 设备验证码 Appkey = map.get("userName").trim();// AppKey channelName = Integer.parseInt(map.get("channelNum").trim());// channelName String secret = map.get("userPwd").trim();// Secret //System.out.println("---测试参数--"+appkey+"---"+secret); if (accessToken.equals("")) { loadingDialg.createLoadingDialog(context, "访问令牌获取中...").show(); // 获取访问令牌 mmap = new HashMap<>(); mmap.put("appKey", Appkey); mmap.put("appSecret", secret); new Thread(new Runnable() { @Override public void run() { response = NetHelper.submitPostData("https://open.ys7.com/api/lapp/token/get", mmap, "utf-8");//encode mHandler.sendEmptyMessage(0); } }).start(); } else { openAPK(); } } } }); findViewById(R.id.back).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO 自动生成的方法存根 VideoListActivity.this.finish(); } }); curve3.setOnClickListener(view -> { Intent intent = new Intent(VideoListActivity.this, DeviceMapActivity.class); intent.putExtra("intentLat",intentLat); intent.putExtra("intentLng",intentLng); intent.putExtra("isShowTitle",true); startActivity(intent); }); } private void initData() { //mvideolist = VideoActivity.videolist; Bundle bundle = getIntent().getExtras(); mvideolist = (ArrayList<Map<String, String>>) bundle.get("list"); aliasname = bundle.getString("aliasname"); user_control_power = bundle.getString("user_control_power"); site_control_power = bundle.getString("site_control_power"); netmode = bundle.getString("netmode"); } protected void openAPK() { // 首先判断SD卡是否可用 if (!FileUtils.getSDcard()) { Toast.makeText(this, "外部存储不可用,此功能禁用", Toast.LENGTH_SHORT).show(); } // 判断SD卡是否已安装 else if (!FileUtils.checkInstall(getApplicationContext(), package_name)) { AlertDialog.Builder builder = new AlertDialog.Builder(VideoListActivity.this); builder.setTitle("提示").setMessage("未安装视频插件,是否安装?") .setPositiveButton("安装", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // 读取APK readApk(); } }).setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { } }); AlertDialog dialog = builder.create(); dialog.show(); } else { //已安装应用,直接打开应用 //判断是否需要更新 PackageManager pm = context.getPackageManager(); try { //通过包名获取已安装应用的信息,然后获取版本号。在与最新版本号对比是否需要进行更新。 PackageInfo info = pm.getPackageInfo(package_name, 1); int code = info.versionCode; if (curersioncode > code) { //有新版本需要跟新 AlertDialog.Builder builder = new AlertDialog.Builder(VideoListActivity.this); builder.setTitle("提示").setMessage("视频插件需要更新,请点击安装!") .setPositiveButton("安装", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // 读取APK readApk(); } }).setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { } }); AlertDialog dialog = builder.create(); dialog.show(); } else { //不需要更新,直接打开APK startApk2(); } } catch (NameNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } protected void openAPK2() { // 首先判断SD卡是否可用 if (!FileUtils.getSDcard()) { Toast.makeText(this, "外部存储不可用,此功能禁用", Toast.LENGTH_SHORT).show(); } // 判断SD卡是否已安装 else if (!FileUtils.checkInstall(getApplicationContext(), package_name2)) { AlertDialog.Builder builder = new AlertDialog.Builder(VideoListActivity.this); builder.setTitle("提示").setMessage("未安装视频插件,是否安装?") .setPositiveButton("安装", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // 读取APK readApk2(); } }).setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { } }); AlertDialog dialog = builder.create(); dialog.show(); } else { //已安装应用,直接打开应用 //判断是否需要更新 PackageManager pm = context.getPackageManager(); try { //通过包名获取已安装应用的信息,然后获取版本号。在与最新版本号对比是否需要进行更新。 PackageInfo info = pm.getPackageInfo(package_name2, 1); int code = info.versionCode; if (curersioncode2 > code) { //有新版本需要跟新 AlertDialog.Builder builder = new AlertDialog.Builder(VideoListActivity.this); builder.setTitle("提示").setMessage("视频插件需要更新,请点击安装!") .setPositiveButton("安装", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { // 读取APK readApk2(); } }).setNegativeButton("取消", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { } }); AlertDialog dialog = builder.create(); dialog.show(); } else { //不需要更新,直接打开APK startApk3(); } } catch (NameNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } protected void readApk() { InputStream in1 = null; OutputStream out; FileUtils fileUtils = new FileUtils(); AssetManager am = getAssets(); byte[] buffer = new byte[1024]; int read; try { in1 = am.open(APK_NAME); File file = new File(fileUtils.getSDPATH() + APK_NAME); file.createNewFile(); out = new FileOutputStream(file); while ((read = in1.read(buffer)) != -1) { out.write(buffer, 0, read); } out.flush(); in1.close(); out.close(); } catch (IOException e) { } finally { try { in1.close(); } catch (IOException e) { } } installApk(APK_NAME); } protected void readApk2() { InputStream in1 = null; InputStream in2 = null; InputStream in3 = null; InputStream in4 = null; InputStream in5 = null; OutputStream out = null; FileUtils fileUtils = new FileUtils(); AssetManager am = getAssets(); byte[] buffer = new byte[1024]; int read = 0; try { in1 = am.open("zxcv1.apk"); in2 = am.open("zxcv2.apk"); in3 = am.open("zxcv3.apk"); in4 = am.open("zxcv4.apk"); in5 = am.open("zxcv5.apk"); if (!fileUtils.isFileExist(APK_NAME2) && new File(fileUtils.getSDPATH() + APK_NAME2).length() < 1) { File file = new File(fileUtils.getSDPATH() + APK_NAME2); file.createNewFile(); out = new FileOutputStream(file); while ((read = in1.read(buffer)) != -1) { out.write(buffer, 0, read); } while ((read = in2.read(buffer)) != -1) { out.write(buffer, 0, read); } while ((read = in3.read(buffer)) != -1) { out.write(buffer, 0, read); } while ((read = in4.read(buffer)) != -1) { out.write(buffer, 0, read); } while ((read = in5.read(buffer)) != -1) { out.write(buffer, 0, read); } out.flush(); in1.close(); in2.close(); in3.close(); in4.close(); in5.close(); out.close(); } } catch (IOException e) { } finally { try { in1.close(); in2.close(); in3.close(); in4.close(); in5.close(); } catch (IOException e) { } } installApk(APK_NAME2); } protected void installApk(String apkName) { //得到了Android外部存储目录 String fileName = Environment.getExternalStorageDirectory() + "/" + apkName; Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); Uri uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileProvider", new File(fileName)); intent.setDataAndType(uri, "application/vnd.android.package-archive"); this.startActivity(intent); } protected void startApk2() { ComponentName componentName = new ComponentName("com.hik.netsdk.SimpleDemo", "com.hik.netsdk.SimpleDemo.View.MainActivity"); Intent intent = new Intent(); // Intent intent = new Intent("chroya.foo"); Bundle bundle = new Bundle(); /* bundle.putString("serial", "811729242");//摄像机序列号 bundle.putString("VerifyCode", "CFEJRH");//摄像机验证码 bundle.putString("accessToken", "at.13zoz9dj48txpxtmbtdbxyp86yppa0kv-8377rzprmz-1ga3ixh-2csonzo9x");//访问令牌,7天过期。 */ bundle.putString("appkey", Appkey);//Appkey bundle.putString("serial", devserial);//摄像机序列号 bundle.putString("VerifyCode", VerifyCode);//摄像机验证码 bundle.putString("accessToken", accessToken);//访问令牌 bundle.putInt("cameraNo", channelName);//通道号 intent.putExtras(bundle); intent.setComponent(componentName); startActivity(intent); } protected void startApk3() { ComponentName componentName = new ComponentName("com.example.funsdkdemo", "com.example.funsdkdemo.Xm4GSDKActivity"); Intent intent = new Intent(); // Intent intent = new Intent("chroya.foo"); Bundle bundle = new Bundle(); /* bundle.putString("serial", "811729242");//摄像机序列号 bundle.putString("VerifyCode", "CFEJRH");//摄像机验证码 bundle.putString("accessToken", "at.13zoz9dj48txpxtmbtdbxyp86yppa0kv-8377rzprmz-1ga3ixh-2csonzo9x");//访问令牌,7天过期。 */ bundle.putString("xmip", xmip); bundle.putString("xmport", xmport); bundle.putString("xmusername", xmusername); bundle.putString("xmpassword", xmpassword); bundle.putString("devSn", devSn); bundle.putString("xmmark", xmmark); //System.out.println("---aaa---"+xmip+"--"+xmport+"--"+xmusername+"--"+xmpassword+"--"+devSn+"--"+xmmark); intent.putExtras(bundle); intent.setComponent(componentName); startActivity(intent); } } 跨应用ysy1.apk的MainActivity:package com.hik.netsdk.SimpleDemo.View; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.Intent; import android.graphics.PixelFormat; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.ImageButton; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.core.view.GravityCompat; import androidx.drawerlayout.widget.DrawerLayout; // 添加 UnstableApi 注解支持 import androidx.media3.common.util.UnstableApi; import androidx.media3.common.MediaItem; import androidx.media3.common.Player; import androidx.media3.common.PlaybackException; import androidx.media3.datasource.DataSource; import androidx.media3.datasource.DefaultHttpDataSource; import androidx.media3.exoplayer.ExoPlayer; import androidx.media3.exoplayer.hls.HlsMediaSource; import androidx.media3.exoplayer.source.MediaSource; import com.hik.netsdk.SimpleDemo.R; import com.videogo.openapi.EZConstants; import com.videogo.openapi.EZOpenSDK; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.util.concurrent.TimeUnit; import okhttp3.Call; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; // 在类级别添加 @UnstableApi 注解 @UnstableApi public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback { // 核心参数 private String mDeviceSerial; private String mVerifyCode; private int mCameraNo = 1; private boolean isEzDevice = false; // 萤石云相关参数 private String mAppKey = "a794d58c13154caeb7d2fbb5c3420c65"; private String mAccessToken = ""; // UI组件 private SurfaceView mPreviewSurface; private SurfaceHolder mSurfaceHolder; private Toolbar m_toolbar; private ProgressBar mProgressBar; private RelativeLayout mControlLayout; private ImageButton mRotateButton; // 播放器相关 private ExoPlayer mExoPlayer; private String mPlaybackUrl; private final OkHttpClient mHttpClient = new OkHttpClient.Builder() .connectTimeout(15, TimeUnit.SECONDS) .readTimeout(15, TimeUnit.SECONDS) .build(); // 播放器状态监听器 private final Player.Listener mPlayerListener = new Player.Listener() { @Override public void onPlaybackStateChanged(int state) { switch (state) { case Player.STATE_READY: mProgressBar.setVisibility(View.GONE); Log.d("ExoPlayer", "播放准备就绪"); break; case Player.STATE_BUFFERING: mProgressBar.setVisibility(View.VISIBLE); Log.d("ExoPlayer", "缓冲中..."); break; case Player.STATE_ENDED: Log.d("ExoPlayer", "播放结束"); break; case Player.STATE_IDLE: Log.d("ExoPlayer", "空闲状态"); break; } } @Override public void onPlayerError(PlaybackException error) { Log.e("ExoPlayer", "播放错误: " + error.getMessage()); handleError("播放错误: " + error.getMessage(), -1); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activitymain); // 初始化UI组件 initUIComponents(); // 获取启动参数 parseIntentParams(); // 初始化SDK initSDK(); // 参数校验 if (mDeviceSerial == null || mDeviceSerial.isEmpty()) { showErrorAndFinish("设备序列号不能为空"); return; } Log.d("MainActivity", "onCreate完成: isEzDevice=" + isEzDevice); } @SuppressLint("WrongViewCast") private void initUIComponents() { // 基础UI m_toolbar = findViewById(R.id.titlename); setSupportActionBar(m_toolbar); // 预览相关UI mPreviewSurface = findViewById(R.id.realplay_sv); mSurfaceHolder = mPreviewSurface.getHolder(); mSurfaceHolder.addCallback(this); mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT); mProgressBar = findViewById(R.id.liveProgressBar); mControlLayout = findViewById(R.id.rl_control); mRotateButton = findViewById(R.id.ib_rotate2); // 设置旋转按钮点击事件 mRotateButton.setOnClickListener(v -> changeScreen()); if (m_toolbar != null) { m_toolbar.setVisibility(View.GONE); } // 初始化控制按钮 initControlButtons(); Log.d("UI", "UI组件初始化完成"); } private void parseIntentParams() { // 获取Intent参数 Intent intent = getIntent(); isEzDevice = true; // 只支持萤石设备 mAccessToken = intent.getStringExtra("accessToken"); // 优先使用bundle Bundle bundle = intent.getExtras(); if (bundle != null) { mDeviceSerial = bundle.getString("devSn"); mVerifyCode = bundle.getString("verifyCode"); mCameraNo = bundle.getInt("cameraNo", 1); } // 兼容直接Extra方式 if (mDeviceSerial == null) mDeviceSerial = intent.getStringExtra("devSn"); if (mVerifyCode == null) mVerifyCode = intent.getStringExtra("verifyCode"); if (mCameraNo == 0) mCameraNo = intent.getIntExtra("cameraNo", 1); Log.d("Params", "设备序列号: " + mDeviceSerial + ", 通道号: " + mCameraNo); } private void initSDK() { try { // 使用反射检查初始化状态 boolean isInitialized = false; try { EZOpenSDK instance = EZOpenSDK.getInstance(); if (instance != null) { isInitialized = true; } } catch (Exception e) { isInitialized = false; } // 未初始化时进行初始化 if (!isInitialized) { EZOpenSDK.initLib(getApplication(), mAppKey); Log.d("EZSDK", "萤石SDK初始化完成"); } // 设置AccessToken if (mAccessToken != null && !mAccessToken.isEmpty()) { EZOpenSDK.getInstance().setAccessToken(mAccessToken); Log.d("EZToken", "AccessToken设置成功"); } else { Log.w("EZToken", "AccessToken缺失!"); } } catch (Exception e) { Log.e("EZSDK", "萤石SDK初始化失败", e); handleError("萤石SDK初始化失败: " + e.getMessage(), -1); } } private void initControlButtons() { // 云台控制按钮 findViewById(R.id.ptz_top_btn).setOnClickListener(v -> controlPTZ("UP")); findViewById(R.id.ptz_bottom_btn).setOnClickListener(v -> controlPTZ("DOWN")); findViewById(R.id.ptz_left_btn).setOnClickListener(v -> controlPTZ("LEFT")); findViewById(R.id.ptz_right_btn).setOnClickListener(v -> controlPTZ("RIGHT")); // 变焦控制 findViewById(R.id.focus_add).setOnClickListener(v -> controlZoom("ZOOM_IN")); findViewById(R.id.foucus_reduce).setOnClickListener(v -> controlZoom("ZOOM_OUT")); // 水平布局控制按钮 findViewById(R.id.ptz_top_btn2).setOnClickListener(v -> controlPTZ("UP")); findViewById(R.id.ptz_bottom_btn2).setOnClickListener(v -> controlPTZ("DOWN")); findViewById(R.id.ptz_left_btn2).setOnClickListener(v -> controlPTZ("LEFT")); findViewById(R.id.ptz_right_btn2).setOnClickListener(v -> controlPTZ("RIGHT")); Log.d("Controls", "控制按钮初始化完成"); } @Override public void surfaceCreated(SurfaceHolder holder) { Log.d("Surface", "Surface created"); // 获取播放地址并开始播放 new Thread(this::fetchPlaybackUrl).start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d("Surface", "Surface changed: " + width + "x" + height); if (mExoPlayer != null) { mExoPlayer.setVideoSurfaceHolder(holder); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { Log.d("Surface", "Surface destroyed"); stopPreview(); } // ======================== 播放地址获取与播放 ======================== private void fetchPlaybackUrl() { try { // 构建请求参数 JSONObject params = new JSONObject(); params.put("accessToken", mAccessToken); params.put("deviceSerial", mDeviceSerial); params.put("channelNo", mCameraNo); params.put("protocol", 2); // 使用HLS协议 if (mVerifyCode != null && !mVerifyCode.isEmpty()) { params.put("code", mVerifyCode); } params.put("expireTime", 7200); // 2小时有效期 // 创建请求体 RequestBody body = RequestBody.create( MediaType.parse("application/json"), params.toString() ); // 创建请求 Request request = new Request.Builder() .url("https://open.ys7.com/api/lapp/v2/live/address/get") .post(body) .build(); // 执行请求 try (Response response = mHttpClient.newCall(request).execute()) { if (!response.isSuccessful()) { handleError("获取播放地址失败: " + response.code(), response.code()); return; } // 解析响应 String responseBody = response.body().string(); JSONObject json = new JSONObject(responseBody); if ("200".equals(json.getString("code"))) { JSONObject data = json.getJSONObject("data"); mPlaybackUrl = data.getString("url"); Log.d("PlaybackURL", "获取到播放地址: " + mPlaybackUrl); // 在主线程初始化播放器 runOnUiThread(this::initExoPlayer); } else { handleError("API错误: " + json.getString("msg"), json.getInt("code")); } } } catch (JSONException | IOException e) { Log.e("FetchURL", "获取播放地址异常", e); handleError("获取播放地址异常: " + e.getMessage(), -1); } } private void initExoPlayer() { // 释放现有播放器 if (mExoPlayer != null) { mExoPlayer.release(); } // 创建播放器 mExoPlayer = new ExoPlayer.Builder(this).build(); mExoPlayer.addListener(mPlayerListener); // 设置视频渲染器 mExoPlayer.setVideoSurfaceHolder(mSurfaceHolder); // 创建媒体源 DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory(); MediaSource mediaSource = new HlsMediaSource.Factory(dataSourceFactory) .createMediaSource(MediaItem.fromUri(Uri.parse(mPlaybackUrl))); // 准备播放 mExoPlayer.setMediaSource(mediaSource); mExoPlayer.prepare(); mExoPlayer.setPlayWhenReady(true); mProgressBar.setVisibility(View.VISIBLE); Log.d("ExoPlayer", "播放器初始化完成,开始播放"); } // ======================== 萤石云控制方法 ======================== private int mapDirection(String direction) { switch (direction) { default: return -1; } } private void controlPTZ(String direction) { int directionCode = mapDirection(direction); if (directionCode == -1) return; // 控制逻辑实现 } private void controlZoom(String command) { String direction = "ZOOM_IN".equals(command) ? "ZOOM_IN" : "ZOOM_OUT"; controlPTZ(direction); } // ======================== 通用功能方法 ======================== public void changeScreen(View view) { changeScreen(); } private void changeScreen() { if (mControlLayout.getVisibility() == View.VISIBLE) { mControlLayout.setVisibility(View.GONE); } else { mControlLayout.setVisibility(View.VISIBLE); } } private void handleError(String message, int errorCode) { String fullMessage = message + " (错误码: " + errorCode + ")"; // 萤石云特有错误码处理 switch (errorCode) { case 400001: fullMessage = "AccessToken无效"; break; case 400002: fullMessage = "设备不存在"; break; case 400007: fullMessage = "设备不在线"; break; case 400034: fullMessage = "验证码错误"; break; case 400035: fullMessage = "设备已被自己添加"; break; case 400036: fullMessage = "设备已被别人添加"; break; default: fullMessage = "萤石云错误: " + errorCode; } new AlertDialog.Builder(this) .setTitle("预览失败") .setMessage(fullMessage) .setPositiveButton("确定", (d, w) -> finish()) .setCancelable(false) .show(); } private void showErrorAndFinish(String message) { Toast.makeText(this, message, Toast.LENGTH_LONG).show(); new Handler().postDelayed(this::finish, 3000); } private void stopPreview() { if (mExoPlayer != null) { mExoPlayer.release(); mExoPlayer = null; Log.d("Preview", "预览已停止"); } } @Override protected void onDestroy() { super.onDestroy(); stopPreview(); Log.d("Lifecycle", "onDestroy"); } @Override protected void onPause() { super.onPause(); if (mExoPlayer != null) { mExoPlayer.setPlayWhenReady(false); Log.d("Lifecycle", "暂停播放"); } } @Override protected void onResume() { super.onResume(); if (mExoPlayer != null) { mExoPlayer.setPlayWhenReady(true); Log.d("Lifecycle", "恢复播放"); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main_opt, menu); return true; } }
06-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值