Python发送邮件附带MP4视频后无法播放问题排查求助
问题根源与修复方案
你的代码存在两个核心问题,导致视频附件下载后无法播放:
重复编码导致文件损坏
你手动创建了MIMEBase对象并完成Base64编码,但随后调用msg.add_attachment()时,这个方法会自动对传入的内容进行编码处理,相当于对已经编码过的视频数据再次编码,彻底破坏了原始文件的字节结构。缺少必要的附件头信息
没有给MIMEBase对象设置Content-Disposition头,邮件客户端无法正确识别这是一个附件,也无法准确解析文件名和文件类型,进而导致下载后的文件无法被播放器识别。
修复方案一:正确使用MIMEBase并手动附加
import smtplib from email import encoders from email.mime.base import MIMEBase from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from_addr = 'FROM_MAIL' to_addr = 'TO_ADDRESS' # 构建多部分邮件对象 msg = MIMEMultipart() msg['From'] = "person_sending@gmail.com" msg['To'] = "person_receiving@gmail.com" msg['Subject'] = 'text for the subject line' # 添加邮件正文 msg.attach(MIMEText('text that will be in the email body.', 'plain')) # 读取并处理视频附件 with open('example.mp4', "rb") as f: video_file = MIMEBase('application', "octet-stream") video_file.set_payload(f.read()) # 编码为Base64 encoders.encode_base64(video_file) # 必须添加Content-Disposition头,指定附件属性 video_file.add_header('Content-Disposition', 'attachment', filename="example.mp4") # 用attach()方法添加,而非add_attachment() msg.attach(video_file) # 发送邮件 server = smtplib.SMTP('smtp.gmail.com', 587) server.ehlo() server.starttls() server.login(from_addr, 'APP_PASS') server.send_message(msg, from_addr=from_addr, to_addrs=[to_addr]) server.quit()
修复方案二:使用MIMEApplication简化处理
这个方案更简洁,无需手动编码,直接用MIMEApplication处理二进制文件:
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication from_addr = 'FROM_MAIL' to_addr = 'TO_ADDRESS' msg = MIMEMultipart() msg['From'] = "person_sending@gmail.com" msg['To'] = "person_receiving@gmail.com" msg['Subject'] = 'text for the subject line' msg.attach(MIMEText('text that will be in the email body.', 'plain')) # 直接用MIMEApplication读取并封装视频文件 with open('example.mp4', 'rb') as f: video_attachment = MIMEApplication(f.read(), _subtype='octet-stream') video_attachment.add_header('Content-Disposition', 'attachment', filename="example.mp4") msg.attach(video_attachment) # 发送邮件 server = smtplib.SMTP('smtp.gmail.com', 587) server.ehlo() server.starttls() server.login(from_addr, 'APP_PASS') server.send_message(msg, from_addr=from_addr, to_addrs=[to_addr]) server.quit()
关键注意事项
- 二选一:要么手动创建MIME对象并设置完整头信息后用
attach()添加,要么直接用add_attachment()传入原始字节和参数(无需提前编码),避免重复编码。 - 必须设置
Content-Disposition头,明确标记为附件并指定文件名,确保邮件客户端能正确解析。 - 使用
with语句打开文件,自动关闭句柄,避免资源泄漏。
内容的提问来源于stack exchange,提问作者hobik
相关产品推荐
相关产品推荐

