mirror of https://github.com/AlfredoSequeida/fvid
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
56612d7143
|
@ -37,12 +37,16 @@ Linux/OSX
|
|||
|
||||
```
|
||||
fvid -i [input file] -e
|
||||
fvid -i [input file] --framerate 30 -e
|
||||
fvid -i [input file] --password "wow fvid is cool" -e
|
||||
```
|
||||
|
||||
Windows
|
||||
|
||||
```
|
||||
py -m fvid -i [input file] -e
|
||||
py -m fvid -i [input file] --framerate 30 -e
|
||||
py -m fvid -i [input file] --password "wow fvid is cool" -e
|
||||
```
|
||||
|
||||
Retrieving data from videos
|
||||
|
@ -59,6 +63,7 @@ Windows
|
|||
py -m fvid -i [input video] -d
|
||||
```
|
||||
|
||||
If the file was encoded with a non-default password, it'll prompt you to enter the password upon decoding.
|
||||
|
||||
How to Contribute
|
||||
-----------------
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
__version__ = "0.0.2"
|
||||
__version__ = "1.0.0"
|
||||
|
||||
|
|
|
@ -1,5 +1,28 @@
|
|||
import sys
|
||||
from fvid import main
|
||||
|
||||
# leaving this here in case the try/except thing doesn't work
|
||||
"""
|
||||
import platform
|
||||
import distro # to check linux distributions
|
||||
|
||||
try:
|
||||
linux_distro = distro.linux_distribution()[0].lower()
|
||||
except:
|
||||
linux_distro = "n/a"
|
||||
|
||||
# fvid
|
||||
if platform.system().lower() in ('linux', 'darwin') and linux_distro not in ('artix linux',):
|
||||
# this used to work for every distro but something changed in the Cython/Password PR
|
||||
from fvid import main
|
||||
else:
|
||||
# windows and artix linux need this because of something in the Cython/Password PR, unknown if more OSes need it
|
||||
from fvid.fvid import main
|
||||
"""
|
||||
|
||||
try:
|
||||
from fvid import main
|
||||
except:
|
||||
from fvid.fvid import main
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
sys.exit(main())
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#cython: language_level = 3
|
||||
from distutils.core import Extension, setup
|
||||
from Cython.Build import cythonize
|
||||
|
||||
ext = Extension(name="fvid_cython", sources=["fvid_cython.pyx"])
|
||||
setup(ext_modules=cythonize(ext, compiler_directives={'language_level': 3, 'infer_types': True}))
|
40
fvid/fvid.py
40
fvid/fvid.py
|
@ -1,19 +1,12 @@
|
|||
from bitstring import Bits, BitArray
|
||||
from PIL import Image
|
||||
import glob
|
||||
|
||||
from operator import sub
|
||||
import numpy as np
|
||||
from tqdm import tqdm
|
||||
|
||||
import binascii
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import os
|
||||
|
||||
import getpass
|
||||
|
||||
import getpass
|
||||
import io
|
||||
import gzip
|
||||
import pickle
|
||||
|
@ -23,6 +16,11 @@ from cryptography.hazmat.primitives import hashes
|
|||
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
try:
|
||||
from fvid_cython import cy_get_bits_from_image as cy_gbfi
|
||||
use_cython = True
|
||||
except (ImportError, ModuleNotFoundError):
|
||||
use_cython = False
|
||||
|
||||
FRAMES_DIR = "./fvid_frames/"
|
||||
SALT = '63929291bca3c602de64352a4d4bfe69'.encode() # It need be the same in one instance of coding/decoding
|
||||
|
@ -54,8 +52,6 @@ def get_password(password_provided):
|
|||
key = kdf.derive(password)
|
||||
return key
|
||||
|
||||
|
||||
|
||||
def get_bits_from_file(filepath, key):
|
||||
print('Reading file...')
|
||||
bitarray = BitArray(filename=filepath)
|
||||
|
@ -87,6 +83,10 @@ def less(val1, val2):
|
|||
return val1 < val2
|
||||
|
||||
def get_bits_from_image(image):
|
||||
if use_cython:
|
||||
bits = cy_gbfi(image)
|
||||
return bits, False
|
||||
|
||||
width, height = image.size
|
||||
|
||||
done = False
|
||||
|
@ -94,11 +94,10 @@ def get_bits_from_image(image):
|
|||
px = image.load()
|
||||
bits = ""
|
||||
|
||||
pbar = range(height)
|
||||
white = (255, 255, 255)
|
||||
black = (0, 0, 0)
|
||||
|
||||
for y in pbar:
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
|
||||
pixel = px[x, y]
|
||||
|
@ -111,14 +110,9 @@ def get_bits_from_image(image):
|
|||
elif pixel == black:
|
||||
pixel_bin_rep = "0"
|
||||
else:
|
||||
white_diff = tuple(map(abs, map(sub, white, pixel)))
|
||||
# min_diff = white_diff
|
||||
black_diff = tuple(map(abs, map(sub, black, pixel)))
|
||||
|
||||
|
||||
# if the white difference is smaller, that means the pixel is closer
|
||||
# to white, otherwise, the pixel must be black
|
||||
if all(map(less, white_diff, black_diff)):
|
||||
if abs(pixel[0] - 255) < abs(pixel[0] - 0) and abs(pixel[1] - 255) < abs(pixel[1] - 0) and abs(pixel[2] - 255) < abs(pixel[2] - 0):
|
||||
pixel_bin_rep = "1"
|
||||
else:
|
||||
pixel_bin_rep = "0"
|
||||
|
@ -128,7 +122,6 @@ def get_bits_from_image(image):
|
|||
|
||||
return (bits, done)
|
||||
|
||||
|
||||
def get_bits_from_video(video_filepath):
|
||||
# get image sequence from video
|
||||
print('Reading video...')
|
||||
|
@ -143,6 +136,8 @@ def get_bits_from_video(video_filepath):
|
|||
bits = ""
|
||||
sequence_length = len(image_sequence)
|
||||
print('Bits are in place')
|
||||
if use_cython:
|
||||
print('Using Cython...')
|
||||
for index in tqdm(range(sequence_length)):
|
||||
b, done = get_bits_from_image(image_sequence[index])
|
||||
|
||||
|
@ -153,7 +148,6 @@ def get_bits_from_video(video_filepath):
|
|||
|
||||
return bits
|
||||
|
||||
|
||||
def save_bits_to_file(file_path, bits, key):
|
||||
# get file extension
|
||||
|
||||
|
@ -203,7 +197,6 @@ def split_list_by_n(lst, n):
|
|||
for i in range(0, len(lst), n):
|
||||
yield lst[i : i + n]
|
||||
|
||||
|
||||
def make_image_sequence(bitstring, resolution=(1920, 1080)):
|
||||
width, height = resolution
|
||||
|
||||
|
@ -213,7 +206,6 @@ def make_image_sequence(bitstring, resolution=(1920, 1080)):
|
|||
# bit_sequence = []
|
||||
print('Making image sequence')
|
||||
print('Cutting...')
|
||||
#bitlist = list(tqdm(split_list_by_n(bitstring, set_size)))
|
||||
bitlist = list(split_list_by_n(bitstring, set_size))
|
||||
|
||||
del bitstring
|
||||
|
@ -225,8 +217,6 @@ def make_image_sequence(bitstring, resolution=(1920, 1080)):
|
|||
print('Saving frames...')
|
||||
for _ in tqdm(range(len(bitlist))):
|
||||
bitl = bitlist.pop()
|
||||
# for bitl in tqdm(bitlist):
|
||||
# image_bits = list(map(int, tqdm(bitl)))
|
||||
image_bits = list(map(int, bitl))
|
||||
# print(image_bits)
|
||||
|
||||
|
@ -237,7 +227,6 @@ def make_image_sequence(bitstring, resolution=(1920, 1080)):
|
|||
)
|
||||
index += 1
|
||||
|
||||
|
||||
def make_video(output_filepath, framerate="1/5"):
|
||||
|
||||
if output_filepath == None:
|
||||
|
@ -262,7 +251,6 @@ def setup():
|
|||
if not os.path.exists(FRAMES_DIR):
|
||||
os.makedirs(FRAMES_DIR)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="save files as videos")
|
||||
parser.add_argument(
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,38 @@
|
|||
# distutils: language=c
|
||||
# cython: boundscheck=False
|
||||
# cython: cdivision=True
|
||||
# cython: wraparound=False
|
||||
|
||||
cpdef str cy_get_bits_from_image(image):
|
||||
cdef int width, height, x, y
|
||||
cdef str pixel_bin_rep, bits
|
||||
cdef (int, int, int) pixel
|
||||
|
||||
width, height = image.size
|
||||
|
||||
px = image.load()
|
||||
bits = ""
|
||||
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
pixel = px[x, y]
|
||||
|
||||
pixel_bin_rep = <str>"0"
|
||||
|
||||
# for exact matches, indexing each pixel individually is faster in cython for some reason
|
||||
if pixel[0] == 255 and pixel[1] == 255 and pixel[2] == 255:
|
||||
pixel_bin_rep = <str>"1"
|
||||
elif pixel[0] == 0 and pixel[1] == 0 and pixel[2] == 0:
|
||||
pixel_bin_rep = <str>"0"
|
||||
else:
|
||||
# if the white difference is smaller (comparison part 1), that means the pixel is closer
|
||||
# to white, otherwise, the pixel must be black
|
||||
if abs(pixel[0] - 255) < abs(pixel[0] - 0) and abs(pixel[1] - 255) < abs(pixel[1] - 0) and abs(pixel[2] - 255) < abs(pixel[2] - 0):
|
||||
pixel_bin_rep = <str>"1"
|
||||
else:
|
||||
pixel_bin_rep = <str>"0"
|
||||
|
||||
# adding bits
|
||||
bits += pixel_bin_rep
|
||||
|
||||
return bits
|
38
setup.py
38
setup.py
|
@ -1,7 +1,28 @@
|
|||
import os
|
||||
import codecs
|
||||
|
||||
from setuptools import setup
|
||||
from setuptools import Extension
|
||||
from setuptools.command.build_ext import build_ext as _build_ext
|
||||
|
||||
try:
|
||||
from Cython.Build import cythonize
|
||||
except ImportError:
|
||||
use_cython = False
|
||||
ext = 'c'
|
||||
else:
|
||||
use_cython = True
|
||||
ext = 'pyx'
|
||||
|
||||
if not use_cython:
|
||||
extensions = Extension("fvid.fvid_cython", ["fvid/fvid_cython.c"], include_dirs=["./fvid", "fvid/"])
|
||||
else:
|
||||
extensions = Extension("fvid.fvid_cython", ["fvid/fvid_cython.pyx"], include_dirs=["./fvid", "fvid/"])
|
||||
extensions = cythonize(extensions, compiler_directives={'language_level': "3", 'infer_types': True})
|
||||
|
||||
|
||||
class build_ext(_build_ext):
|
||||
def finalize_options(self):
|
||||
_build_ext.finalize_options(self)
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
@ -41,10 +62,9 @@ setup(
|
|||
"Intended Audience :: End Users/Desktop",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.4",
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Operating System :: Microsoft :: Windows :: Windows 10",
|
||||
"Operating System :: Microsoft :: Windows :: Windows 8",
|
||||
"Operating System :: Microsoft :: Windows :: Windows 8.1",
|
||||
|
@ -53,14 +73,20 @@ setup(
|
|||
],
|
||||
license="MIT",
|
||||
packages=["fvid"],
|
||||
setup_requires=[
|
||||
"cython >= 3.0a6"
|
||||
],
|
||||
install_requires=[
|
||||
"bitstring",
|
||||
"python-magic",
|
||||
"pillow",
|
||||
"numpy",
|
||||
"tqdm",
|
||||
"ffmpeg-python",
|
||||
"cryptography >= 3.1.1",
|
||||
"pycryptodome >= 3.9.8"
|
||||
],
|
||||
python_requires=">=3.6",
|
||||
entry_points={"console_scripts": ["fvid = fvid.fvid:main"]},
|
||||
ext_modules=extensions,
|
||||
cmdclass={'build_ext': build_ext},
|
||||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue