通过二进制的方式下载视频

一.需求:前台通过多线程的方式多次调用后台下载视频接口,在短时间下载一个内存较大的视频。
二.实现原理:
1. 前台在下载视频的时候会创建一个原始视频总大小的临时文件,然后开启多线程,每个线程下载一个视频片段,每个下载完成的视频片段都会填充在临时文件的指定位置。所以该方法需要的参数是:sliceOffset切片视频的位置; sliceSize每个切片视频的大小。
2.输入流:

            FileInputStream fis = new FileInputStream(file);
			fis.skip(sliceOffset);//从指定位置读取字节
			InputStream bis = new BufferedInputStream(fis);//输入流

输出流:

		OutputStream toClient = new BufferedOutputStream(response.getOutputStream());//输出流
			response.reset();//清除首部空白行
			response.setContentType("application/octet-stream");//设置客户端接收的数据类型,这里是 二进制
			response.setContentLength(sliceSize);//输出长度

具体代码如下:

1.控制层

@PostMapping(value = "downloadVideoSlice")
	public ServerResponse<?> downloadVideoSlice(HttpServletRequest request, HttpServletResponse response) {
		Integer stAutoId = Integer.parseInt(request.getParameter("stAutoId"));
		Integer iId = Integer.parseInt(request.getParameter("iId"));
		Integer sliceOffset = Integer.parseInt(request.getParameter("sliceOffset"));
		Integer sliceSize = Integer.parseInt(request.getParameter("sliceSize"));
		String path = (String) iImageService.downloadVideoSlice(stAutoId, iId).getData();
		// 将文件转化成流输出
		FileUtil.getOutputStream(path, response, sliceOffset, sliceSize);
		return null;
	}

2.实现类(涉及到业务,可以忽略这部分)

@Override
	public ServerResponse<?> downloadVideoSlice(int stAutoId, int iId) {
		Tstudy tstudy = tstudyMapper.selectByPrimaryKey((long) stAutoId);
		Date stDate = tstudy.getStStartdate();
		String stDate_str = DateTimeUtil.dateToStr(stDate, "yyyy-MM-dd HH:mm:ss");
		VStorageNodeMethod method = CommonConfigCache.getVStorageNodeMethodByDate(stDate, tstudy.getStHospitalcode(),
				StorageNodeType.IMAGE, StorageMethodType.DOWNLOAD, Method.HTTP.getType());
		String httpHead = method.getSmnHttpVirtualPath();
		String rootPath = method.getSnRootpath();

		if (method == null) {
			return ServerResponse.createByErrorMessage("查无此图");
		}
		// 获取图片表
		String stDate_str1 = DateTimeUtil.dateToStr(stDate, "yyyyMMdd");

		Timagecontrol timagecontrol = CommonConfigCache.getTimagecontrol("US", stDate_str1);

		TimageExample timageExample = new TimageExample();
		timageExample.createCriteria().andIIdEqualTo((long) iId);
		timageExample.setOrderByClause("I_Number");
		List<Timage> timages = timageMapper.selectByExampleWithTableName(timagecontrol.getcImagetablename(),
				timageExample);
		Timage timage = null;
		if (CollectionUtils.isNotEmpty(timages) && timages.size() > 0) {
			timage = timages.get(0);
		}
		String serverpath = timage.getiServerpath();
		String filePath = rootPath + serverpath.replace("/", "\\");
		return ServerResponse.createBySuccess(filePath);
	}

3.工具类(重点)

Http ContentTpye对照表

/**
	 * 将文件转化成流输出
	 * 
	 * @param path
	 * @param response
	 * @param sliceOffset
	 * @param sliceSize
	 */
	public static void getOutputStream(String path, HttpServletResponse response, Integer sliceOffset,
			Integer sliceSize) {

		File file = new File(path);
		try {
			FileInputStream fis = new FileInputStream(file);
			fis.skip(sliceOffset);//从指定位置读取字节
			InputStream bis = new BufferedInputStream(fis);//输入流
			OutputStream toClient = new BufferedOutputStream(response.getOutputStream());//输出流
			response.reset();//清除首部空白行
			response.setContentType("application/octet-stream");//设置客户端接收的数据类型,这里是 二进制
			response.setContentLength(sliceSize);//输出长度
			// 数据缓冲区
			byte[] arr = new byte[1024];
			int len;
			long count = 0;
			// 数据读写
			while ((len = bis.read(arr)) != -1) {
				// 分三种情况
				if (len + count > sliceSize) {
					// 1.当读取的时候操作自己该线程的下载总量的时候,需要改变len
					len = (int) (sliceSize - count);
					toClient.write(arr, 0, len);
					// 证明该线程下载任务已经完毕,结束读写操作
					break;
				} else if (len + count < sliceSize) {
					// 2.证明还没有到下载总量,直接将内容写入
					toClient.write(arr, 0, len);
					// 并且使计数器任务累加
					count += arr.length;
				} else {
					// 3.证明改好到下载总量
					toClient.write(arr, 0, len);
					// 结束读写
					break;
				}
			}
			toClient.close();
			bis.close();
			fis.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	} ```

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 如果你想获取网络上某个URL对应的图片或视频二进制资源,你可以使用Response类的 `content` 属性。 这个属性可以返回一个二进制数据,你可以将它写入文件,或者使用相应的库进行处理,如使用 `PIL` 库处理图像数据,或者使用 `opencv` 库处理视频数据。 示例代码: ```python import requests # 获取图片二进制数据 response = requests.get('http://example.com/image.jpg') image_data = response.content # 将二进制数据写入文件 with open('image.jpg', 'wb') as f: f.write(image_data) ``` 注意: - 如果需要处理大量的二进制数据,建议使用流式读取数据的方式,可以使用 `iter_content` 方法。 - 如果你只想获取响应的文本内容,应该使用 `text` 属性,这个属性会将响应的内容解码为字符串。 ### 回答2: 获取网络上某个URL对应的图片或视频二进制资源,应该使用Response类的content属性。 Response类是Python requests库中的一个重要类,它表示HTTP请求的响应。content属性是Response类中的一个属性,用于获取响应内容的二进制形式。 当通过requests库发送GET请求获取一个URL对应的内容时,可以使用Response类来接收响应。使用content属性可以获取响应内容的二进制形式,包括图片、视频二进制资源。 使用content属性的示例代码如下: ```python import requests url = "https://example.com/image.jpg" # 替换为实际的URL response = requests.get(url) if response.status_code == 200: content = response.content # 获取响应内容的二进制形式 with open("image.jpg", "wb") as file: file.write(content) # 将二进制内容保存到文件中 print("图片下载成功!") else: print("图片下载失败!") ``` 上述代码中,首先通过requests库发送GET请求获取URL对应的响应。然后,判断响应的状态码是否为200,如果是则表示请求成功。接着,使用content属性获取响应内容的二进制形式,并将其写入文件中保存。最后,打印下载成功或失败的信息。 通过使用Response类的content属性,可以获取URL对应的图片或视频二进制资源,并进行后续的处理。 ### 回答3: 获取网络上某个URL对应的图片或视频二进制资源,应该使用Response类的`content`属性。 Response类是requests模块中的一个类,用于处理HTTP响应。通过发送HTTP请求,可以得到服务器返回的Response对象,其中包含了响应的内容。 在Response类中,`content`属性用于获取HTTP响应的内容。对于图片或视频二进制资源,可以使用`content`属性来获取它们的二进制数据。 使用方法如下: ```python import requests url = 'http://example.com/image.jpg' response = requests.get(url) # 获取图片的二进制数据 image_data = response.content # 将图片保存到本地 with open('image.jpg', 'wb') as file: file.write(image_data) ``` 上述代码中,`response`对象表示发送到`url`的HTTP响应。通过访问`response.content`属性,我们可以获取到该响应的二进制内容,然后可以将其保存到本地文件中或进行其他处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值