今天解决一个调用微信永久素材上传视频的问题,在网上查了很久,上传视频的接口写的都不一样而且到处复制,感觉很乱,于是在做完case之后做了一个整理,希望能够帮助到你们.
涉及到如何调用微信永久素材上传视频以及上传后如何通过mediaid和获取永久素材接口得到该视频对应的url的,然后保存至本地,然后通过调用微信的url直接读取视频,拿默认回复中的视频来举例。(YII1框架)
首先:
前端页面中一个上传按钮,在上传了之后通过js回调将视频文件先上传到服务器上对应的文件夹中,这个没什么好说的。
jQuery('#video_upload').dmUploader({ url: '<?php echo Yii::app()->createAbsoluteUrl('Manager/DefaultMessages/videoUpload'); ?>', dataType : 'json', fileName : 'upload', allowedTypes : 'video/*', maxFileSize : 10485760, onUploadSuccess: function(id, data){ if(data.result == 'success'){ videoUpload.find('video').attr('src',data.url); }else{ alert(data.result); } }, onFileSizeError: function(file){ alert('<?php echo Yii::t("manager", "Unsupported file size!"); ?>') }, onFileTypeError: function(file){ alert('<?php echo Yii::t("manager", "Unsupported file type!"); ?>') } });
这个是Controller中上传video的方法
public function actionVideoUpload(){ $fileName = $_FILES['upload']['name']; $extensions = array('.mp4'); $extensionName = ''; foreach ($extensions as $extension) { if(stripos($fileName, $extension) !== false){ $extensionName = $extension; break; } } if($extensionName){ $filePath = $_FILES['upload']['tmp_name']; $des = dirname(__FILE__).'/../../../../upload/videos/defaultMessage/'; //目录及权限 if(!is_dir($des)){ mkdir($des, 0777, true); } $timeStamp = time(); //成功则返回服务器所在视频的地址 if(move_uploaded_file($filePath, $des.$timeStamp.$extensionName)){ echo json_encode(array('result'=>'success','url'=>'http://'.$_SERVER['HTTP_HOST'].'/upload/videos/defaultMessage/'.$timeStamp.$extensionName)); }else{ echo json_encode(array('result'=>'failed')); } }else{ echo json_encode(array('result'=>Yii::t('manager', 'Unsupported file type!'))); } }
然后是save以后的处理。
public function actionModify() { //这里是我项目里面获取defaultmessage的内容的,不用看 $mid = Helper::getManagerId(); $model = DefaultMessages::model()->find('mid = :mid', array(':mid' => $mid)); if (!$model) { $model = new DefaultMessages(); $model->mid = $mid; } if(isset($_POST['DefaultMessages'])) { //上传或修改如果改变了视频,则同步上传到微信并保存微信的mediaId,这里根据前端自己做相应的判断,注意如果视频没有改变的话不要上传视频,否则素材空间很快就会满掉。 if($_POST['DefaultMessages']['replyType']==5&&($model->mediaId !=$_POST['DefaultMessages']['mediaId'])){ $filePath = $_POST['DefaultMessages']['mediaId']; //微信需要的title $video_title = substr($filePath,-14); //视频所在服务器上的路径 $filePath= dirname(__FILE__).'/../../../../upload/videos/defaultMessage/'.$mid.$video_title; //微信需要的introduction描述 $introduction = 'default_message_video'; //上传并获取media_id $media_id = Media::addMaterial($mid, 'video', $filePath,true, $video_title, $introduction); //通过mediaid调用获取永久素材接口获取微信视频存储的url $wechat_url = Media::getMaterial($mid,$media_id); //保存mediaid为微信视频存放的url $_POST['DefaultMessages']['mediaId'] = $wechat_url; $model->attributes=$_POST['DefaultMessages']; } if ($model->save()) { $this->redirect(array('modify')); }else{ var_dump($model->getErrors());die(); } } $this->render('modify', array( 'model' => $model, )); }
上面调用的addmaterial函数
public static function addMaterial($mid, $type, $filePath, $is_video=false, $video_title='', $introduction='') { $json = WechatMedia::addMaterial(AccessToken::getAccessToken($mid), $type, $filePath, $is_video, $video_title, $introduction);//下面有函数,token的拼接就不贴出来了 $result = json_decode($json, TRUE); //成功则返回mediaid用于后面根据mediaid获取视频url if (!isset($result['media_id'])) { return false; } return $result['media_id']; }
上面调用的material函数
public static function addMaterial($access_token, $type, $filePath, $is_video, $video_title, $introduction) { //$api_url 类似这个https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=....&type=video $api_url = self::getApiUrl('add_material'); if ($api_url) { $params = array(); if ($is_video) { $params['description'] = urldecode(json_encode(array( 'title' => $video_title, 'introduction' => $introduction ))); } //版本不同好像media有所不同 if (version_compare(PHP_VERSION, '5.5.0') < 0 ) { $params['media'] = '@'.$filePath; } else { $params['media'] = new CURLFile($filePath); } return HttpCurl::post($api_url, $params); } return false; }
post方法
public static function post($url, $keysArr, $header=array(), $flag = 0) { $ch = curl_init(); if (!$flag) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); } if(count($header) > 0) { curl_setopt($ch, CURLOPT_HTTPHEADER, $header); } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $keysArr); curl_setopt($ch, CURLOPT_URL, $url); $ret = curl_exec($ch); $err = curl_error($ch); //yii记录日志用的不用看 if($err){ Yii::log("curl error ::".$err, 'error', 'Curl Error'); Yii::log("curl error url ::".$url, 'error', 'Curl Error'); } curl_close($ch); return $ret; }
通过mediaid调用微信获取永久素材接口获取微信视频存储的地址
public static function getMaterial($mid, $media_id) { $json = WechatMedia::getMaterial(AccessToken::getAccessToken($mid), $media_id); $result = json_decode($json, TRUE); //微信那里的地址是down_url,存在则返回 if(isset($result['down_url'])){ return $result['down_url']; } return false; }
获取永久素材的地址
public static function getMaterial($access_token, $media_id) { //Apiurl类似于https://api.weixin.qq.com/cgi-bin/material/get_material?access_token..... $apiUrl = self::getApiUrl('get_material'); if ($apiUrl) { $params = array( 'media_id' => $media_id ); //这里注意要json一下,至于post方法上面有就不贴了 return HttpCurl::post($apiUrl, json_encode($params)); } else { return false; } }
这样存在数据库中的mediaid就是微信的视频的地址了,应该算是比较完整的一段流程了0.0