[Connection Debug] The confused 2440 first lesson

2023-01-23   ES  

Video files are preserved in unknown places.
Play on the front end

<video controls="controls" controls="controls">
  <source src="http://ip:port/xxxxxxx" type="video/mp4" />
</video>

src = back -end interface
If the back end is written directly like this

	// PATH is the local file.
    public void play(String path, HttpServletRequest request, HttpServletResponse response) {
    
        // Get video file stream
        FileInputStream fileInputStream = null;
        OutputStream outputStream = null;
        try {
    
            outputStream = response.getOutputStream();
            fileInputStream = new FileInputStream(new File(path));
        byte[] cache = new byte[1024];
            response.setHeader(HttpHeaders.CONTENT_TYPE, "video/mp4");
            response.setHeader(HttpHeaders.CONTENT_LENGTH, fileInputStream.available()+"");
        int flag;
        while ((flag = fileInputStream.read(cache)) != -1) {
    
            outputStream.write(cache, 0, flag);
        }
        outputStream.flush();
        outputStream.close();
        }catch (Exception e){
    
            log.error("File transmission error", e);
            throw new RuntimeException("File transmission error");
        } finally{
    
            if(outputStream != null){
    
                try {
    
                    outputStream.close();
                } catch (IOException e) {
    
                    log.error("Stream release error", e);
                }
            }
            if(fileInputStream != null){
    
                try {
    
                    fileInputStream.close();
                } catch (IOException e) {
    
                    log.error("File stream release error", e);
                }
            }
        }
    }

Small video problem is not big. If the video is big, it will be stuck for a long time. View request finds that you will first ask to download the full video and start playing. And you cannot drag the progress bar for play. The reason for pursuing is because Video will send a detection request to obtain information of the video, length, etc., and then began to play. It cannot be dragged for the progress of the progress bar because the obtaining video interface does not support breakpoint transmission, so it can only be viewed in order.
http requests have related breakpoint transmission protocols. HTTP protocol status code 206 is the protocol that implements breakpoint transmission. The HTTP request header needs to specify the scope of the obtaining data: Range: bytes = First-Ent, First, start the data of the data. Index position, end, ending the index position of the data. The HTTP response requires the specified range response head: Content-Range bytes first-end-end-end-end-end-on, and the HTTP status code is set to 206.
So the approximate thinking of the video breakpoint playback is to identify whether the HTTP request header is carried by the Range request header. If you carry it, it means that the request needs to be downloaded. After a certain range of reading and writing, return the Content-Range request header to indicate the range of the return data, and set the HTTP status code to 206 to represent the breakpoint transmission. code show as below

	// PATH is the local file.
	public void play(String path, HttpServletRequest request, HttpServletResponse response) {
    

        RandomAccessFile targetFile = null;
        OutputStream outputStream = null;
        try {
    
            outputStream = response.getOutputStream();
            response.reset();
            // Get the value of Range in the request header
            String rangeString = request.getHeader(HttpHeaders.RANGE);

            // Open the file
            File file = new File(path);
            if (file.exists()) {
    
                // Use RandomacCessfile to read files
                targetFile = new RandomAccessFile(file, "r");
                long fileLength = targetFile.length();
                long requestSize = (int) fileLength;
                // Segment download video
                if (StringUtils.hasText(rangeString)) {
    
                    // Extracted from the start and end of the data from the Range
                    long requestStart = 0, requestEnd = 0;
                    String[] ranges = rangeString.split("=");
                    if (ranges.length > 1) {
    
                        String[] rangeDatas = ranges[1].split("-");
                        requestStart = Integer.parseInt(rangeDatas[0]);
                        if (rangeDatas.length > 1) {
    
                            requestEnd = Integer.parseInt(rangeDatas[1]);
                        }
                    }
                    if (requestEnd != 0 && requestEnd > requestStart) {
    
                        requestSize = requestEnd - requestStart + 1;
                    }
                    // Set the request header according to the protocol
                    response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
                    response.setHeader(HttpHeaders.CONTENT_TYPE, "video/mp4");
                    if (!StringUtils.hasText(rangeString)) {
    
                        response.setHeader(HttpHeaders.CONTENT_LENGTH, fileLength + "");
                    } else {
    
                        long length;
                        if (requestEnd > 0) {
    
                            length = requestEnd - requestStart + 1;
                            response.setHeader(HttpHeaders.CONTENT_LENGTH, "" + length);
                            response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + requestStart + "-" + requestEnd + "/" + fileLength);
                        } else {
    
                            length = fileLength - requestStart;
                            response.setHeader(HttpHeaders.CONTENT_LENGTH, "" + length);
                            response.setHeader(HttpHeaders.CONTENT_RANGE, "bytes " + requestStart + "-" + (fileLength - 1) + "/"
                                    + fileLength);
                        }
                    }
                    // Break -point transmission download video Return 206
                    response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
                    // Set targetFile and read data from the custom position
                    targetFile.seek(requestStart);
                } else {
    
                    // If Range is empty, download the entire video
                    response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=test.mp4");
                    // Set the file length
                    response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileLength));
                }

                // Read the data stream from the disk to return
                byte[] cache = new byte[4096];
                try {
    
                    while (requestSize > 0) {
    
                        int len = targetFile.read(cache);
                        if (requestSize < cache.length) {
    
                            outputStream.write(cache, 0, (int) requestSize);
                        } else {
    
                            outputStream.write(cache, 0, len);
                            if (len < cache.length) {
    
                                break;
                            }
                        }
                        requestSize -= cache.length;
                    }
                } catch (IOException e) {
    
                    // tomcat original words. The writing operation IO abnormalities are almost always caused by the client's active turnover connection, so eat the abnormal diary directly
                    // For example, when using Video to play videos, the range of Range 0- is often sent to get the video size, and then it is interrupted and connected.
                    log.info(e.getMessage());
                }
            } else {
    
                throw new RuntimeException("File roads are wrong");
            }
            outputStream.flush();
        } catch (Exception e) {
    
            log.error("File transmission error", e);
            throw new RuntimeException("File transmission error");
        }finally {
    
            if(outputStream != null){
    
                try {
    
                    outputStream.close();
                } catch (IOException e) {
    
                    log.error("Stream release error", e);
                }
            }
            if(targetFile != null){
    
                try {
    
                    targetFile.close();
                } catch (IOException e) {
    
                    log.error("File stream release error", e);
                }
            }
        }
    }

source

Related Posts

HDU4628 (state compression DP)

Blockchain 100 Lecture: Chain code (smart contract) in Hyperledger Fabric

Python uses regular expressions to process HTML comments and labels

Collections.sort sorting two methods for list

[Connection Debug] The confused 2440 first lesson

Random Posts

Android compilation system analysis, detailed explanation of the call order of the MK file after executing Make Bootimage

[.NET code farmer] C# generic programming

janusec waf gateway installation experience

Install two error records that appear in Nagios

ROS2 minimalist summary-core concept (2)