融云如何支持视频消息的功能

融云正式的视频消息还在开发当中 目前 IMLib 完全可以自行开发 , IMKit 也可以通过如下的方式进行视频消息的发送

  1. /** 
  2.      * 发送图片消息上传到服务器 
  3.      * @param firstImgPath  视频第一帧画面的本地 path 
  4.      * @param videoPath     视频存储的本地路径 
  5.      * @param mConversationType  会话类型 
  6.      * @param targetId  目标id 
  7.      */  
  8.     public void sendVideoMessage(String firstImgPath,final String videoPath, Conversation.ConversationType mConversationType,String targetId) {  
  9.         if (TextUtils.isEmpty(firstImgPath)) {  
  10.             new RuntimeException(“firstImgPath is null”);  
  11.             return;  
  12.         }  
  13.   
  14.         File f = new File(firstImgPath);  
  15.         if (!f.exists()) {  
  16.             new RuntimeException(“image file is null”);  
  17.             return;  
  18.         }  
  19.         if (TextUtils.isEmpty(videoPath)) {  
  20.             new RuntimeException(“videoPath is null”);  
  21.             return;  
  22.         }  
  23.         if (mConversationType == null) {  
  24.             new RuntimeException(“ConversationType is null”);  
  25.             return;  
  26.         }  
  27.         if (TextUtils.isEmpty(targetId)) {  
  28.             new RuntimeException(“targetId is null”);  
  29.             return;  
  30.         }  
  31.   
  32.         ImageMessage imageMessage = ImageMessage.obtain(Uri.parse(“file://” + firstImgPath), Uri.parse(“file://” + firstImgPath));  
  33.         io.rong.imlib.model.Message message = io.rong.imlib.model.Message.obtain(targetId, mConversationType, imageMessage);  
  34.         RongIM.getInstance().getRongIMClient().sendImageMessage(message, nullnullnew RongIMClient.SendImageMessageWithUploadListenerCallback() {  
  35.             @Override  
  36.             public void onAttached(final io.rong.imlib.model.Message message, final RongIMClient.uploadImageStatusListener watcher) {  
  37.                 message.setSentStatus(Message.SentStatus.SENDING);  
  38.                 RongIMClient.getInstance().setMessageSentStatus(message.getMessageId(), message.getSentStatus());  
  39.                 Runnable runnable = new Runnable() {  
  40.                     @Override  
  41.                     public void run() {  
  42.                         ImageMessage img = (ImageMessage) message.getContent();  
  43.                         img.setLocalUri(Uri.parse((videoPath)));  
  44.   
  45.                         io.rong.imlib.model.Message msg = io.rong.imlib.model.Message.obtain(message.getTargetId(), message.getConversationType(), img);  
  46.                         RongIMClient.getInstance().uploadMedia(msg, new RongIMClient.UploadMediaCallback() {  
  47.                             @Override  
  48.                             public void onProgress(io.rong.imlib.model.Message message, int progress) {  
  49.                                 watcher.update(progress);  
  50.                             }  
  51.   
  52.                             @Override  
  53.                             public void onError(io.rong.imlib.model.Message message, RongIMClient.ErrorCode errorCode) {  
  54.                                 watcher.error();  
  55.                             }  
  56.   
  57.                             @Override  
  58.                             public void onSuccess(io.rong.imlib.model.Message message) {  
  59.                                 watcher.success();  
  60.                             }  
  61.                         });//  
  62.                     }  
  63.                 };  
  64.                 new Handler().post(runnable);  
  65.             }  
  66.   
  67.             @Override  
  68.             public void onError(io.rong.imlib.model.Message message, RongIMClient.ErrorCode code) {  
  69.   
  70.             }  
  71.   
  72.             @Override  
  73.             public void onSuccess(io.rong.imlib.model.Message message) {  
  74.                 message.setSentStatus(Message.SentStatus.SENT);  
  75.                 RongIMClient.getInstance().setMessageSentStatus(message.getMessageId(), message.getSentStatus());  
  76.             }  
  77.   
  78.             @Override  
  79.             public void onProgress(io.rong.imlib.model.Message message, int progress) {  
  80.   
  81.             }  
  82.         });  
  83.     }  

 

对上面这段代码做下讲解 : 上面的代码片段已经封装好了一个完整的 可以直接发送视频的方法 只要你是集成的 融云 2.26+ 以上的版本 你就可以把上面的代码 copy 过去直接用了 注意 cpoy 过去需要自己处理一下包名

然后我们看看 四个参数 : 会话类型 和 id 就不用多解释了 这个来确定你需要像谁发这个消息 , fristImgPath 这个参数就是视频的 第一帧的图 这个是个 file:/// 的本地路径  因为最终消息是需要在会话界面上做展示 然后你看到的第一帧的图片点击以后 开始下载播放视频  再来看  videoPath 也是一个本地的 视频路径 下面我们来看一下具体用法:

imkit_video_img

通过上图可见 我已经准备好了一个 测试的 videotest.mp4 视频文件  5MB

  1.             //获取到 视频的 第一帧的 bitmap  
  2.             MediaMetadataRetriever mmr = new MediaMetadataRetriever();  
  3.             mmr.setDataSource(“/storage/sdcard1/DCIM/Camera/videotest.mp4″);  
  4.             Bitmap bitmap = mmr.getFrameAtTime();  
  5.             String firstPath = saveMyBitmap(“firstImagePath”,bitmap);  
  6.   
  7.   
  8.             RongIM.getInstance().sendVideoMessage(firstPath,“file:///storage/sdcard1/DCIM/Camera/videotest.mp4″, Conversation.ConversationType.PRIVATE,“32324″);  
  9.             finish();  
  10.         }  
  11.     });  
  12.   
  13.     String[] versionInfo = getVersionInfo();  
  14.     mCurrentVersion.setText(versionInfo[1]);  
  15. }  
  16.   
  17.   
  18. public String saveMyBitmap(String bitName,Bitmap mBitmap){  
  19.     File f = new File(“/storage/sdcard1/DCIM/Camera/” + bitName + “.png”);  
  20.     try {  
  21.         f.createNewFile();  
  22.     } catch (IOException e) {  
  23.   
  24.     }  
  25.     FileOutputStream fOut = null;  
  26.     try {  
  27.         fOut = new FileOutputStream(f);  
  28.     } catch (FileNotFoundException e) {  
  29.         e.printStackTrace();  
  30.     }  
  31.     mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);  
  32.     try {  
  33.         fOut.flush();  
  34.     } catch (IOException e) {  
  35.         e.printStackTrace();  
  36.     }  
  37.     try {  
  38.         fOut.close();  
  39.     } catch (IOException e) {  
  40.         e.printStackTrace();  
  41.     }  
  42.     return “/storage/sdcard1/DCIM/Camera/” + bitName + “.png”;  
  43. }  

通过上面代码 您可以看到 我先获取本地的 视频文件路径 然后通过 Android 的 Media 获取到了视频的第一帧的 bitmap 然后通过 saveMyBitmap() 方法 将bitmap 转换为保存为本地 路径 并且返回 uri 给我 这样先获取到了第一帧的参数  视频的 路径我们已经有的 然后就可以直接对某个用户做发送了

 

当我先调用获取第一帧的方法 我们先看看 手机内到底生成了那张图片没有

imkit_video

目前可以根据上图看到  第一帧 在调用过方法后 已经生成  1.97MB 有点大 这么是测试 所以没有进行压缩 有需要的开发者在这里可以自行进行压缩  路径 和 文件名也和我们上面代码中的相吻合

 

下面我们来看一下 视频第一帧展示在界面上 并且视频上传的进度展示 由于此处进度最好需要视频来展示 这边笔者截取了好几帧的发送过程给大家做展示

imkit_video_ upload

 

可以从上图看到 视频在界面上首先展示了第一帧的 图片 然后上传视频的 进度也一直在刷  35% 74% 88%  到最后发送完成的图片在下面

imkit_video_end

 

到此时这个视频消息已经发送完成 视频已经通过融云的 uploadMidea 上传到了 七牛的存储上 变成了一个 RetomeUri 远程路径 接收端也是一样的道理 可以在接收消息的监听里面获取到 这个 ImageMessage (此处完善后应该是 VideoMessage) 两者效果一样都是 调用 uploadMidea 向云上做存储 , 接收端再消息体里面获取到这个 RetomeUri 就可以根据这个 RetomeUri 然后调用 downloadMidea (此方法是向七牛去下载这个视频) 下载到接收端 然后自行做处理

 

注意:uploadMidea  downloadMidea 是融云提供的上传下载方法  此处你可以上传到自己的服务端做存储  另外需要注意的是 在 sendVideoMessage() 方法内 也有 上传进度的回调 我们使用了这个进度 然后也可以看到上面图片上 有视频上传的进度