前几天在微信公众号开发中遇到这么一个有意思的问题,视频在PC端的浏览器中能正常播放,但是在微信公众号中无法正常播放(与PC端使用同一段url),一直报视屏解码异常,经过几个小时的折腾无果,最后无奈只能继续在微信手册中寻求解决方案,最终将目光锁定在微信的素材管理接口上。
为了能给大家更多的借鉴,我把情景具体的描述一下,然后给各位贴上代码,当时我是通过微信对话框上传的视频(即临时拍摄的的小视频或手机本地上原来存在的视频),然后通过微信提供的“获取临时素材”接口:
http请求方式: GET,https调用 https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID将Media_id和access_token作为参数传递给微信,获取视频在微信服务器上的url地址,然而我刚开始思路就是将其直接传给前端让其进行播放,然而只能在浏览器上测试可以播放,但是在微信内置的浏览器中无法播放,故此该方法行不通;再接下来我的思路是将视频下载至本地服务器,再将本地服务器的视频地址传给前端,问题还是一样,没能得到解决,最后不得已只能使用最后一个办法就是将下载下来的视频,在通过微信提供的“上传临时素材”接口,将视频上传至微信,在通过其“获取临时素材”接口获取到url地址,再将其传给前端,问题得到解决,下面我先将代码贴上,再说后续问题。
import urllib2
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
'''
因为这些视频我需要在本地进行备份,所以我需要将其下载至本地,至于model的设计情况,因为安全原因不能提供,下边代码仅供参考,为大家拓展思路
1、将视频通过“获取临时素材”接口下载至本地
2、将下载的视频上传至微信服务器(通过上传临时素材接口)
3、在通过“获取临时素材”接口获取可供在微信内置浏览器中播放的url
4、将改Url返回给前端
'''
def get_weixin_media(request,uuid):
data = {
'ret': '-1',
'data': 'error',
}
if request.method == 'GET':
try:
a = A.objects.get(uuid=uuid) #A是我项目中的一个model
except Exception as e:
data['data'] = '-1'
data['data'] = 'uuid有误'
return HttpResponse(json.dumps(data))
try:
b = B.objects.get(a_id=a.id)
except Exception as e:
data['data'] = '-2'
data['data'] = '没有该借条信息'
return HttpResponse(json.dumps(data))
try:
veri =C.objects.get(related_field_id=B.id)
except Exception as e:
data['data'] = '-3'
data['data'] = '没有该视频认证记录'
return HttpResponse(json.dumps(data))
try:
video = D.objects.get(verifi_id=veri.id)
except Exception as e:
data['data'] = '-4'
data['data'] = '没有该视频,或者media_id过期,有效期只有三天'
return HttpResponse(json.dumps(data))
if 'weixin' in str(video.video) and video.has_downloaded == 0: #has_downloaded是我数据库中用来判断视频有没有被下载的字段
media_id = str(video.video)[7:] #这个media_id需要根据具体情况而定,
print media_id
url = video.down_from_weixin(media_id)
print url
video.video = url
video.has_downloaded = 1
video.save()
data['data'] = url
print 'data:',data
token = get_weixin_token() #通过传给微信appid个appsecret获取access_token
api_url = 'https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=video' % token
#
register_openers()
datas, headers = multipart_encode({"media": open('/home/ring/Desktop/wei'+url, "rb")})
request = urllib2.Request(api_url, datas, headers)
result = eval(urllib2.urlopen(request).read())
for k,v in result.items():
if str(k) == 'media_id':
media_id = str(v)
token = get_weixin_token()
api_url = 'https://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s'%(token,media_id)
req = urllib2.Request(api_url)
response = eval(urllib2.urlopen(req).read())
for k,v in response.items():
if str(k) == 'video_url':
data['data'] = str(v)
return HttpResponse(json.dumps(data))
elif '.' in str(video.video):
data['ret'] = '0'
data['data'] = str(video.video)
import urllib2
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
token = get_weixin_token()
api_url = 'https://api.weixin.qq.com/cgi-bin/media/upload?access_token=%s&type=video' % token
#
register_openers()
datas, headers = multipart_encode({"media": open('/home/ring/Desktop/wei' + str(video.video), "rb")})
request = urllib2.Request(api_url, datas, headers)
result = eval(urllib2.urlopen(request).read())
for k, v in result.items():
if str(k) == 'media_id':
media_id = str(v)
token = get_weixin_token()
api_url = 'https://api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s' % (token, media_id)
req = urllib2.Request(api_url)
response = eval(urllib2.urlopen(req).read())
for k, v in response.items():
if str(k) == 'video_url':
data['data'] = str(v)
return HttpResponse(json.dumps(data))
return HttpResponse(json.dumps(data))
下边我们再来探讨一下上边可能存在的问题:
1、每次都得上传视频到微信,然后获取,即使不是每次,至少也是每三天得传一次,严重浪费带宽、浪费流量、影响网站的整体性能
2、微信对于临时素材有严格限制,不能上传超过10M大小的视频
针对以上这两个问题,后来我请教了一个朋友,他就是使用就视频上传至本地,然后传一个本地url给前端,就能实现播放,通过测试我访问他的公众号,确实是可以正常播放的,但是不知道是出于什么原因,我切换至他的那个分支,拥有跟他同样的代码,然而还是出现视频解码异常的问题,这实在是让我百思不得其解,我现在初步定位问题可能你出现在这两方面:
1、开发环境的问题(个人感觉可能性不大)
2、问题出在我的测试号,可能是我微信测试号有什么地方不对,或者这测试号不稳定什么的,这我还在进一步研究,当我发现问题所在后会在后续博文中与已发表。