通过Python发送视频文件

-3 投票
4 回答
6425 浏览
提问于 2025-04-19 18:13

我需要弄清楚怎么写一个脚本,去扫描一个文件夹里的新文件,如果有新文件,就通过邮件发送这个文件。

我住的公寓里有人一直在偷自行车!最开始是我自己的错(我忘了锁车),现在那个小偷更厉害了,直接把锁链剪了。我真是受够了,尤其是当他用半英寸的飞机钢丝剪掉我的第二辆自行车的时候。

总之,我想用树莓派做一个运动感应的监控摄像头,希望它在录制完视频后,能立即把视频文件发给我。这样如果他们把树莓派也偷走,我还能有证据。

我在看一些例子,但我搞不清楚怎么让这个脚本一直运行(每分钟检查一次),或者怎么让它扫描一个文件夹找新文件。

我该如何使用SMTP发送附件?

好的,我已经把它简化到扫描文件然后尝试发送邮件的步骤了。但是在尝试附加视频文件的时候失败了。你能帮我吗?这是我修改后的代码:

失败信息是:
msg = MIMEMultipart() TypeError: 'LazyImporter' object is not callable, line 38

import time, glob
import smtplib
import email.MIMEMultipart  
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders, MIMEMultipart
import os

#Settings:
fromemail= "Jose Garcia <somerandomemail@gmail.com>"
loginname="somerandomemail@gmail.com"
loginpassword="somerandomepassword"
toemail= "Jose Garcia <somerandomemail@gmail.com>"
SMTPserver='smtp.gmail.com'
SMTPort=587
fileslocation="/Users/someone/Desktop/Test/*.mp4"
subject="Security Notification"

def mainloop():   
        files=glob.glob(fileslocation) #Put whatever path and file format you're using in there.
        while 1:
            new_files=glob.glob(fileslocation)
            if len(new_files)>len(files):
                for x in new_files:
                    if x in files:
                        print("New file detected "+x)
                        print("about to call send email")
                        sendMail(loginname, loginpassword, toemail, fromemail, subject, gethtmlcode(), x, SMTPserver, SMTPort)

            files=new_files
            time.sleep(1)

def sendMail(login, password, to, frome, subject, text, filee, server, port):
#    assert type(to)==list
#    assert type(filee)==list

    msg = MIMEMultipart()
    msg['From'] = frome
    msg['To'] = COMMASPACE.join(to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach( MIMEText(text) )

#    #for filee in files:
    part = MIMEBase('application', "octet-stream")
    part.set_payload( open(filee,"rb").read() )
    Encoders.encode_base64(part)
    part.add_header('Content-Disposition', 'attachment; filename="%s"'
                       % os.path.basename(filee))
    msg.attach(part)

    smtp = smtplib.SMTP(SMTPserver, SMTPort)
    smtp.sendmail(frome, to, msg.as_string() )
    server.set_debuglevel(1) 
    server.starttls() 
    server.ehlo() 
    server.login(login, password) 
    server.sendmail(frome, to, msg) 
    server.quit()

def gethtmlcode():
    print("about to assemble html")
    html = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" '
    html +='"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">'
    html +='<body style="font-size:12px;font-family:Verdana"><p>A new video file has been recorded </p>'
    html += "</body></html>"
    return(html)

#Execute loop
mainloop()

4 个回答

0

只需把你的脚本放在一个循环里,然后让它每60秒“睡一觉”。你可以用 glob 来获取目录中的文件列表。in 这个东西很有用,可以用来查看列表里的内容(也就是目录中的文件列表)。

import time, glob

files=glob.glob("/home/me/Desktop/*.mp4") #Put whatever path and file format you're using in there.

while 1:
    new_files=glob.glob("/home/me/Desktop/*.mp4")
    if len(new_files)>len(files):
        for x in new_files:
            if x not in files:
                print("New file: "+x) #This is where you would email it. Let me know if you need help figuring that out.
    files=new_files
    time.sleep(60)
1

我用的是python3,怎么也搞不定这些例子,但我想出了一个简单得多的方法,结果可以正常工作。

import smtplib
from email.message import EmailMessage
from email.mime.base import MIMEBase
from email import encoders

# Defining Objects and Importing Files ------------------------------------

# Initializing video object
video_file = MIMEBase('application', "octet-stream")

# Importing video file
video_file.set_payload(open('video.mkv', "rb").read())

# Encoding video for attaching to the email
encoders.encode_base64(video_file)

# creating EmailMessage object
msg = EmailMessage()

# Loading message information ---------------------------------------------
msg['From'] = "person_sending@gmail.com"
msg['To'] = "person_receiving@gmail.com"
msg['Subject'] = 'text for the subject line'
msg.set_content('text that will be in the email body.')
msg.add_attachment(video_file, filename="video.mkv")

# Start SMTP Server and sending the email ---------------------------------
server=smtplib.SMTP_SSL('smtp.gmail.com',465)
server.login("person_sending@gmail.com", "some-clever-password")
server.send_message(msg)
server.quit()
1

看起来,email模块随着时间的推移进行了重构。 这解决了我在Python 2.7中遇到的'LazyImporter'对象不可调用的错误:

from email.mime.text import MIMEText

值得注意的是,它对我认为是同义词的写法,比如import email; email.mime.text.MIMEText(...)并不满意。

1

我终于搞定了。为了消除LazyImporter错误,我不得不使用Python 2.5。每当在安全文件夹里添加一个新文件时,它就会发邮件通知我。不过,日志功能坏掉了。

import time, glob
import smtplib
from email.MIMEMultipart import MIMEMultipart 
from email.MIMEMultipart import MIMEBase 
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
import datetime 
from email import Encoders
import os
import sys


#Settings:
fromemail= 'RaspberryPI Security Camera <someone>'
loginname='someone@gmail.com'
loginpassword='something'
toemail= 'Jose Garcia < someone@gmail.com>'
SMTPserver='smtp.gmail.com'
SMTPort=587
fileslocation='/Users/someone/Desktop/Test/*.*'
subject="Security Notification"
log='logfile.txt'

def mainloop():   
        files=glob.glob(fileslocation) #Put whatever path and file format you're using in there.
        while 1:
            f = open(log, 'w')
            sys.stdout = Tee(sys.stdout, f)
            new_files=glob.glob(fileslocation)
            if len(new_files)>len(files):
                for x in new_files:
                    if x in files:
                        print(str(datetime.datetime.now()) + "New file detected "+x)
                        sendMail(loginname, loginpassword, toemail, fromemail, subject, gettext(), x, SMTPserver, SMTPort)
            files=new_files
            f.close()
            time.sleep(1)

def sendMail(login, password, send_to, send_from, subject, text, send_file, server, port):

    msg = MIMEMultipart()
    msg['From'] = send_from
    msg['To'] = COMMASPACE.join(send_to)
    msg['Date'] = formatdate(localtime=True)
    msg['Subject'] = subject

    msg.attach( MIMEText(text) )

    part = MIMEBase('application', "octet-stream")
    part.set_payload( open(send_file,"rb").read() )
    Encoders.encode_base64(part)
    part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(send_file))
    msg.attach(part)

    smtp = smtplib.SMTP(SMTPserver, SMTPort)
    smtp.set_debuglevel(1) 
    smtp.ehlo() 
    smtp.starttls() 
    smtp.login(login, password) 
    smtp.sendmail(send_from, send_to, msg.as_string() )
    smtp.close()


def gettext():
    text = "A new file has been added to the security footage folder. \nTime Stamp: "+ str(datetime.datetime.now())
    return(text)

class Tee(object):
    def __init__(self, *files):
        self.files = files
    def write(self, obj):
        for f in self.files:
            f.write(obj)


#Execute loop
mainloop()

撰写回答