Recentemente, uma tarefa apareceu diariamente para formar um lapso de tempo com um par de câmeras de vigilância conectadas ao IPEYE. Se você está interessado em saber como uma pessoa com conhecimento mínimo de python lidou com isso, ou se deseja apontar meus erros para mim, bem-vindo ao…
Introdução
Meu pai decidiu se mudar e construir uma casa em outra região. Ele me pediu para ajudar com a vigilância por vídeo. Dados de entrada:
- Não há sala técnica.
- O equipamento pode ser roubado.
- Precisa de uma imagem de qualidade.
- As câmeras devem estar ao ar livre.
- Tudo que você precisa é de 2 câmeras.
- Eu realmente quero câmeras PTZ com zoom.
- Eu gostaria de uma aplicação móvel.
Tendo analisado os preços nas lojas de equipamentos de marca, decidiu-se comprar câmeras PoE que não eram de nome com todos os pães de Ali. As câmeras eram baratas o suficiente - cerca de 5 mil cada.
Eu não queria colocar o DVR em um canteiro de obras, por isso foi decidido usar uma solução em nuvem. Depois que as câmeras chegaram, tentei fazer amizade com diferentes serviços para que tudo funcionasse, incluindo o PTZ. De todos os serviços que experimentei, acabei fazendo amigos de câmeras chinesas apenas com IPEYE.
Isso encerrará a introdução. Penso que agora ficará claro para todos por que a conversa será sobre esse serviço.
Experiência com IPEYE
Serviço como um serviço. Tudo prometido está cumprido. O suporte técnico responde a perguntas. O ponto principal é que você pode especificar um link para o fluxo rstp, alterar as configurações de PTZ e tudo funcionará. Aplicativo móvel Android funciona. É possível criar usuários convidados para suas câmeras e conceder direitos de acesso a cada parente. A interface da Web no Vivaldi às vezes é de buggy; no Chrome, essas falhas são menos comuns. Um pouco monótono navegando no arquivo.
O arquivo da câmera pode ser baixado, mas por até 3 horas. O procedimento é bastante demorado.
Tudo parece estar bem, mas você sente com a alma que algo não está certo. E não há profundidade de arquivo suficiente. Você pode aumentar a profundidade, mas a opção mais cara - 12 meses custará 25 mil rublos por ano para uma câmera (ao gravar por detecção).
Vamos inventar alguma coisa?
Essa é a pergunta que meu pai me fez. Meu pai queria capturar todas as etapas da construção.
Quais são as opções para resolver este problema? Você pode acessar a interface da Web diariamente e exportar vários vídeos de cada câmera. Quem executará uma tarefa tão sombria? Ninguém! Várias vezes ao dia para abrir câmeras de transmissão e tirar screenshots? Bem, também insanidade. Aumentar a profundidade do arquivo para 1 ano? Bem, uma solução muito barata. O Google me disse que a função TimeLapse já está embutida neste serviço, mas a resolução é baixa e você não pode baixá-lo para o futuro arquivo :(
UPD: O timelapse original pode ser baixado. Para fazer isso, abra o lapso de tempo na interface da web. Usando ferramentas de desenvolvedor, inspecione a página da web e encontre um link para nosso arquivo. Formato do Link:
sr <número do servidor> .ipeye.ru / api / v1 / stream / <uuid> / nvr / timelapse / 0 / <unixtimestamp> /100/video.mjpeg
Foi decidido escrever algo para, de alguma forma, salvar as capturas de tela da câmera e formar o vídeo final.
Isenção de responsabilidade
O autor desta obra não é um programador e não procura se tornar um. OOP conhece o básico superficialmente. Ágil, etc. não estudado. Há um mês, ele assistiu a um breve curso em vídeo sobre python e decidiu usá-lo para resolver o problema atual.
API
Foi muito agradável descobrir que o serviço IPEYE é uma
API disponível publicamente. A API fornece exemplos apenas para PHP, mas provou ser útil.
Com base no fato de meu computador nunca desligar, o seguinte conceito foi desenvolvido:
- O Agendador do Windows executa um script a cada 30 minutos.
- O script através da API determina o uuid das minhas câmeras.
- O script por meio da API recebe a foto das câmeras e a salva em um diretório.
- O script uma vez por dia gera um arquivo de vídeo para cada câmera.
- O catálogo com fotos de origem e vídeos finais é vinculado à nuvem e compartilhado.
- Parentes quando eles querem assistir ao timelapse e operar os arquivos como desejarem.
Para trabalhar com a API, escrevi algumas funções: registrando e executando solicitações no servidor da API.
writeLog ()def writeLog(logdata): if LogEnable == 1: log_time = datetime.now() log_time = log_time.isoformat(timespec='seconds') log_file = open(log_file_path, "a+") log_file.write(log_time + ": " + str(logdata) + "\n") log_file.close else: return True
getApiResponse () def getApiResponse(method, api_uri): if method == "GET": try: r = requests.get(api_url + api_uri, timeout = api_timeout) r.raise_for_status()
De acordo com a API, temos a capacidade de acessar / devices / all e obter informações sobre todos os threads. Fiquei imediatamente confuso ao saber que a autorização não é necessária, se você acredita na documentação da API ... Quando solicitei / devices / all, recebi um erro:
Erro fatal: 401 Erro do cliente: não autorizado para url: api.ipeye.ru : 8111 / devices / all
Modifiquei minha função getApiResponse para passar minhas credenciais, mas também recebi um erro 401. Não listo a função, porque não foi útil no futuro.
Eu tive que entrar em contato com o suporte técnico sobre isso. A equipe de suporte explicou que, para usar a API com autorização, você deve primeiro concluir um contrato com o IPEYE e configurar seu servidor da web. Que tipo de servidor da Web e por que eles não me explicaram, mas ao mesmo tempo deram uma dica sobre como obter câmeras uuid e acessar a API sem autorização.
Correspondência com apoioEu: Boa tarde. É possível usar a API? Não encontrei câmeras uuid na interface da web. Eu queria obter uma lista de minhas câmeras quando perguntei api.ipeye.ru : 8111 / devices / all, exceto meu link de nome de usuário / senha não funcionou.
IPEYE: Como o login / senha, os dados de autorização do usuário da API são usados, fornecemos acesso contratualmente.
Assim, a lista de câmeras que você verá não para o seu login, mas para todas as câmeras da API do usuário.
Eu: quanto custa obter acesso à API de duas câmeras?
IPEYE: Tudo é mais complicado lá, você precisará iniciar seu site e usar nossa API para adicionar câmeras a ele e continuar trabalhando com eles.
Vale a pena fazer por duas câmeras?
Eu: em geral, para entender, eu preciso acessar a API apenas para baixar automaticamente capturas de tela das câmeras. Para a formação adicional de lapso de tempo.
IPEYE: E o que api.ipeye.ru/doc#AppDeviceJPEGOnline não é adequado nesse caso?
Eu: E onde posso encontrar os UUIDs das minhas câmeras?
IPEYE: Na barra de endereços do navegador, por exemplo. O mesmo UUID aparece no "Código do site" como o parâmetro devcode.
O que temos no resíduo seco? De fato, câmeras uuid podem ser encontradas em sua conta, se você observar os parâmetros GET. Existe um método / device / jpeg / online /: uuid /: nome para tirar uma captura de tela, existe uuid e já sabíamos o nome da câmera.
Eu crio uma função para salvar imagens de um fluxo.
saveJpegFromStream () def saveJpegFromStream(uuid, name):
Faço um pedido e entendo que algo não está certo ... Recebemos o arquivo. A imagem é da minha câmera, mas o tamanho é suspeito - 66Kb. Eu olho para as propriedades e entendo que 608 * 342 não é de forma alguma 1920 * 1080. Quando solicito / device / thumb / online / uuid / 1920 / name, recebo o arquivo 1920 * 1080, mas este é apenas o arquivo anterior 608 * 342 estendido para a escala necessária. Obviamente, esse estado de coisas não me agradou.
Também durante as experiências, é descoberto que o parâmetro name não é verificado ou usado de forma alguma. Você pode enviar o que quiser.
Depois disso, concluí que o comando / dispositivo / url / rtsp / mais útil é obter um link para o fluxo RTSP. Eu tive que recorrer ao Google, porque Não havia como entender com o RTSP.
getStreamRTSP () def getStreamRTSP(uuid, name): api_uri = "/device/url/rtsp/" + uuid writeLog("Trying get stream RTSP link for " + name + " " + uuid) response = json.loads(getApiResponse("GET", api_uri).text) writeLog("Stream RTSP link for " + name + ": " + str(response["message"])) return str(response["message"])
saveJpegFromRTSP def saveJpegFromRTSP(name, rtspLink): writeLog("Trying save RTSP screenshot for camera: " + name) rtspClient = cv2.VideoCapture(rtspLink) if rtspClient.isOpened(): _,frame = rtspClient.read() rtspClient.release()
Depois de escrever algumas funções acima, percebi que não havia necessidade de usar a API para a tarefa inicial :) Eu tenho um link direto para o fluxo rtsp da câmera e, com a última função, posso capturar a imagem da câmera. Mas não comecei a mudar o conceito nesta etapa.
Ao trabalhar com a API, há duas vantagens: o servidor IPEYE inicializa o fluxo muito mais rápido que a câmera e o fluxo da câmera rtsp pode ser fechado por um firewall.
jpg2mp4
O último passo é adicionar todas as imagens de uma câmera ao vídeo. Eu escolhi o codec mp4v, porque O MEGA permite reproduzir esses arquivos de vídeo em uma interface da web.
makeVideoFile () def makeVideoFile(name): height = 1080 width = 1920
Para referência: 45 arquivos jpg com um volume total de 37,3 MB no formato de vídeo ocupam 16,9 MB.
Obrigado por ler meu primeiro artigo público. Tentei descrever tudo no formato da história, e não é simples de fazer, porque não queria um artigo seco sobre a saída.
Ficarei feliz em comentar, porque conheci python há menos de um mês.
O script completo com comentários estendidos pode ser encontrado no
github . Além disso, o script leva em consideração a diferença de fuso horário e todas as demais funções são gravadas para serem escaladas rapidamente para um número diferente de câmeras.