Làm cách nào để truyền phát video bằng socket Python?

Chào mừng các bạn đến với phần 2 của hướng dẫn socket với Python. Trong hướng dẫn trước, chúng ta đã học cách gửi và nhận dữ liệu bằng cách sử dụng ổ cắm, nhưng sau đó chúng ta đã minh họa vấn đề có thể phát sinh khi giao tiếp của chúng ta vượt quá kích thước bộ đệm. Trong hướng dẫn này, chúng ta sẽ nói về việc khắc phục điều này

Như đã đề cập trước đây, có một số cách hợp lý mà bạn có thể xử lý cho việc này, nhưng một cách phổ biến là bắt đầu tất cả thư với tiêu đề chứa độ dài của thư sắp đến. Thử thách tiếp theo là bình thường hóa tiêu đề này theo một cách nào đó. Bạn có thể cân nhắc sử dụng một số chuỗi ký tự hoặc một số định dạng, nhưng sau đó bạn có nguy cơ bị mọi người vô tình hoặc cố ý bắt chước định dạng này. Thay vào đó, bạn có thể sử dụng tiêu đề có độ dài cố định, trong đó

f'{len("your message here!"):<10}'
0 byte dữ liệu đầu tiên sẽ là dữ liệu tiêu đề, sẽ bao gồm độ dài của thư sắp tới. Khi chúng tôi đã nhận được độ dài dữ liệu đó, chúng tôi biết mọi thông tin sau đây sẽ là một thông báo mới, nơi chúng tôi cần lấy tiêu đề và tiếp tục lặp lại quy trình này

Vì vậy, những gì chúng ta cần làm bây giờ là chọn một số kích thước tin nhắn thực sự tối đa. Nói, 1.000.000.000 byte. Đúng vậy, hầu như không có trường hợp nào mà ai đó sẽ cố gắng làm bất cứ điều gì gần như thế này thông qua ứng dụng trò chuyện của chúng tôi, vì vậy điều này sẽ ổn thôi. Con số đó là 10 byte (10 ký tự). Trong python, làm cách nào chúng ta có thể biểu thị bất kỳ số nào dưới dạng 10 ký tự? . khái niệm cơ bản. Vì đây là chức năng ít người dùng nên xem thêm tại đây. , mà bạn sẽ thấy các ví dụ như

#Aligning the text and specifying a width:

>>>
>>> '{:<30}'.format('left aligned')
'left aligned                  '
>>> '{:>30}'.format('right aligned')
'                 right aligned'
>>> '{:^30}'.format('centered')
'           centered           '
>>> '{:*^30}'.format('centered')  # use '*' as a fill char
'***********centered***********'

Trong trường hợp này, bạn có thể xem các ví dụ khác nhau trong đó có 30 ký tự được sử dụng mỗi lần, nhưng bạn có thể thực hiện nhiều cách sắp xếp khác nhau. Mặc dù điều này chủ yếu được sử dụng để làm cho GUI dựa trên văn bản trở nên đẹp mắt, nhưng chúng tôi cũng có thể sử dụng điều này cho các mục đích của mình, chẳng hạn như

f'{len("your message here!"):<10}'

Trong trường hợp trên, điều này sẽ tạo ra độ dài của tin nhắn của chúng tôi bằng 10 ký tự

>>> f'{len("your message here!"):<10}'
'18        '

Tất cả những gì chúng ta làm bây giờ chỉ là gửi trước tất cả các tin nhắn của chúng ta với điều này, sau đó chúng ta có thể chuyển đổi 10 ký tự đầu tiên của tin nhắn mới thành một int để biết thêm bao nhiêu là một phần của một tin nhắn duy nhất. Để làm điều này, chúng tôi sẽ bắt đầu trong kịch bản máy chủ của chúng tôi

f'{len("your message here!"):<10}'
1

import socket

HEADERSIZE = 10

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1241))
s.listen(5)

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")

    msg = "Welcome to the server!"
    msg = f"{len(msg):<{HEADERSIZE}}"+msg

    clientsocket.send(bytes(msg,"utf-8"))

Vì vậy, bây giờ tin nhắn của chúng tôi sẽ có tiêu đề gồm 10 ký tự/byte sẽ chứa độ dài của tin nhắn mà khách hàng của chúng tôi sử dụng để thông báo khi nhận được phần cuối của tin nhắn. Hãy làm việc trên

f'{len("your message here!"):<10}'
2 tiếp theo

f'{len("your message here!"):<10}'
2

________số 8_______

Cái này liên quan nhiều hơn một chút, nhưng không có gì quá điên rồ ở đây. Tôi đã tăng bộ đệm lên 16 byte. 8 thậm chí sẽ không đủ để đọc tiêu đề, vì vậy đó sẽ là một vấn đề và có lẽ bạn sẽ không bao giờ có bộ đệm nhỏ như thế này. Chúng tôi chỉ làm ví dụ. Vì vậy, chúng tôi bắt đầu ở trạng thái mà bit dữ liệu tiếp theo chúng tôi nhận được là

f'{len("your message here!"):<10}'
4

Nếu thư là

f'{len("your message here!"):<10}'
4, thì điều đầu tiên chúng tôi làm là phân tích cú pháp tiêu đề mà chúng tôi đã biết là có độ dài cố định gồm 10 ký tự. Từ đây, chúng tôi phân tích độ dài tin nhắn. Sau đó, chúng tôi tiếp tục xây dựng
f'{len("your message here!"):<10}'
6, cho đến khi var đó có kích thước bằng
f'{len("your message here!"):<10}'
7 +
f'{len("your message here!"):<10}'
8 của chúng tôi. Khi điều này xảy ra, chúng tôi sẽ in ra toàn bộ thông báo

Đi từ đây đến một số loại API phát trực tuyến khá đơn giản. Hãy làm một ví dụ trong đó máy chủ chỉ truyền một thứ gì đó đơn giản, chẳng hạn như thời gian hiện tại

Để làm điều này, chúng tôi chỉ cần thêm phần sau vào cuối

    while True:
        time.sleep(3)
        msg = f"The time is {time.time()}"
        msg = f"{len(msg):<{HEADERSIZE}}"+msg

        print(msg)

        clientsocket.send(bytes(msg,"utf-8"))

f'{len("your message here!"):<10}'
1 đầy đủ của chúng tôi bây giờ là

import socket
import time


HEADERSIZE = 10

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1243))
s.listen(5)

while True:
    # now our endpoint knows about the OTHER endpoint.
    clientsocket, address = s.accept()
    print(f"Connection from {address} has been established.")

    msg = "Welcome to the server!"
    msg = f"{len(msg):<{HEADERSIZE}}"+msg

    clientsocket.send(bytes(msg,"utf-8"))

    while True:
        time.sleep(3)
        msg = f"The time is {time.time()}"
        msg = f"{len(msg):<{HEADERSIZE}}"+msg

        print(msg)

        clientsocket.send(bytes(msg,"utf-8"))

Bây giờ, không có gì thay đổi đối với khách hàng của chúng tôi, ngoại trừ việc chuẩn bị rằng chúng tôi sẽ chấp nhận thư mới sau lần đầu tiên, vì vậy chúng tôi cần đặt lại var

f'{len("your message here!"):<10}'
6, vì vậy toàn bộ ________0____2 của chúng tôi trở thành

import socket

HEADERSIZE = 10

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(), 1243))

while True:
    full_msg = ''
    new_msg = True
    while True:
        msg = s.recv(16)
        if new_msg:
            print("new msg len:",msg[:HEADERSIZE])
            msglen = int(msg[:HEADERSIZE])
            new_msg = False

        print(f"full message length: {msglen}")

        full_msg += msg.decode("utf-8")

        print(len(full_msg))


        if len(full_msg)-HEADERSIZE == msglen:
            print("full msg recvd")
            print(full_msg[HEADERSIZE:])
            new_msg = True
            full_msg = ""

Bây giờ, hãy chạy hai thứ này và bạn sẽ thấy máy chủ xuất ra một cái gì đó giống như

28        The time is 1552068299.01783
30        The time is 1552068302.0181189
30        The time is 1552068305.0206459
29        The time is 1552068308.021842
29        The time is 1552068311.024837
29        The time is 1552068314.025016
28        The time is 1552068317.02619
29        The time is 1552068320.026504
29        The time is 1552068323.031633
30        The time is 1552068326.0359411
29        The time is 1552068329.039903
29        The time is 1552068332.040124
30        The time is 1552068335.0402749
27        The time is 1552068338.0437
29        The time is 1552068341.043971

Và khách hàng

new msg len: b'27        '
full message length: 27
16
full message length: 27
32
full message length: 27
37
full msg recvd
The time is 1552068338.0437
new msg len: b'29        '
full message length: 29
16
full message length: 29
32
full message length: 29
39
full msg recvd
The time is 1552068341.043971

Trong hướng dẫn tiếp theo, chúng ta sẽ nói về cách chúng ta có thể gửi các đối tượng Python thay vì chỉ các chuỗi

hướng dẫn tiếp theo. Hướng dẫn về socket với Python 3 phần 3 - gửi và nhận đối tượng Python với socket

Làm cách nào để gửi video qua ổ cắm Python?

Cách gửi âm thanh và video bằng lập trình socket trong Python .
vid = cv2. VideoCapture(tên tệp) FPS = vid. nhận được (cv2. .
nếu khung hình/giây>FPS. TS+=0. 001 yêu tinh khung hình/giây
người thừa hành. submit(audio_stream) # để tạo và gửi luồng trình thực thi dữ liệu âm thanh

Chúng tôi có thể sử dụng ổ cắm IO để truyền phát video không?

Bằng cách sử dụng giao thức WebRTC, chúng tôi có thể truyền phát video ngoài âm thanh và chỉ cần đưa video đó vào phần tử video HTML thay vì phần tử âm thanh .

Truyền trực tuyến có sử dụng ổ cắm không?

Ổ cắm luồng cung cấp luồng dữ liệu không có ranh giới bản ghi . một luồng byte có thể là hai chiều (ứng dụng song công hoàn toàn. nó có thể truyền và nhận qua ổ cắm). Các luồng có thể được dựa vào để cung cấp dữ liệu theo trình tự, không trùng lặp.

Làm cách nào để tạo ứng dụng phát trực tuyến Python?

Các bước để hoàn thành nhiệm vụ này. .
Chúng tôi sẽ tạo một Máy chủ và máy khách
Máy chủ sẽ gửi video cho máy khách và máy khách sẽ chấp nhận
Chúng tôi sẽ quay video bằng thư viện OpenCV ở phía máy chủ
Sau đó, tôi sẽ tuần tự hóa khung thành byte @ phía máy chủ