Spaces:
Runtime error
Runtime error
Commit
·
edb49b9
1
Parent(s):
3f2e082
- app.py +25 -58
- requirements.txt +2 -4
app.py
CHANGED
|
@@ -1,60 +1,51 @@
|
|
| 1 |
import pdb
|
| 2 |
import time
|
| 3 |
-
|
| 4 |
-
|
| 5 |
import streamlit as st
|
| 6 |
import os
|
| 7 |
-
from utils import wm_add_v2, file_reader, model_util, wm_decode_v2, bin_util
|
| 8 |
-
from models import my_model_v7_recover
|
| 9 |
import torch
|
| 10 |
import uuid
|
| 11 |
import datetime
|
| 12 |
import numpy as np
|
| 13 |
import soundfile
|
| 14 |
from huggingface_hub import hf_hub_download, HfApi
|
|
|
|
| 15 |
|
| 16 |
|
| 17 |
# Function to add watermark to audio
|
| 18 |
def add_watermark(audio_path, watermark_text):
|
| 19 |
-
assert len(watermark_text) ==
|
| 20 |
-
|
| 21 |
-
|
| 22 |
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
_, signal_wmd, time_cost = wm_add_v2.add_watermark(watermark, data, 16000, 0.1, device, model)
|
| 26 |
|
| 27 |
tmp_file_name = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + "_" + str(uuid.uuid4()) + ".wav"
|
| 28 |
tmp_file_path = '/tmp/' + tmp_file_name
|
| 29 |
-
soundfile.write(tmp_file_path,
|
| 30 |
return tmp_file_path
|
| 31 |
|
| 32 |
|
| 33 |
# Function to decode watermark from audio
|
| 34 |
def decode_watermark(audio_path):
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
data,
|
| 40 |
-
start_bit,
|
| 41 |
-
0.1,
|
| 42 |
-
16000,
|
| 43 |
-
0.3,
|
| 44 |
-
model,
|
| 45 |
-
device, "best")
|
| 46 |
-
|
| 47 |
-
if mean_result is None:
|
| 48 |
return "No Watermark"
|
| 49 |
|
| 50 |
-
|
| 51 |
-
return bin_util.binArray2HexStr(payload)
|
| 52 |
|
| 53 |
|
| 54 |
# Main web app
|
| 55 |
def main():
|
|
|
|
|
|
|
| 56 |
if "def_value" not in st.session_state:
|
| 57 |
-
|
|
|
|
|
|
|
| 58 |
|
| 59 |
st.title("Neural Audio Watermark")
|
| 60 |
st.write("Choose the action you want to perform:")
|
|
@@ -62,14 +53,15 @@ def main():
|
|
| 62 |
action = st.selectbox("Select Action", ["Add Watermark", "Decode Watermark"])
|
| 63 |
|
| 64 |
if action == "Add Watermark":
|
| 65 |
-
audio_file = st.file_uploader("Upload Audio File (WAV)", type=["wav"], accept_multiple_files=False
|
|
|
|
| 66 |
if audio_file:
|
| 67 |
tmp_input_audio_file = os.path.join("/tmp/", audio_file.name)
|
| 68 |
with open(tmp_input_audio_file, "wb") as f:
|
| 69 |
f.write(audio_file.getbuffer())
|
| 70 |
st.audio(tmp_input_audio_file, format="audio/wav")
|
| 71 |
|
| 72 |
-
watermark_text = st.text_input("Enter Watermark
|
| 73 |
|
| 74 |
add_watermark_button = st.button("Add Watermark", key="add_watermark_btn")
|
| 75 |
if add_watermark_button: # 点击按钮后执行的
|
|
@@ -90,7 +82,8 @@ def main():
|
|
| 90 |
# st.button("Add Watermark", disabled=False)
|
| 91 |
|
| 92 |
elif action == "Decode Watermark":
|
| 93 |
-
audio_file = st.file_uploader("Upload Audio File (WAV/MP3)", type=["wav", "mp3"], accept_multiple_files=False
|
|
|
|
| 94 |
if audio_file:
|
| 95 |
if st.button("Decode Watermark"):
|
| 96 |
# 1.保存
|
|
@@ -110,36 +103,10 @@ def main():
|
|
| 110 |
st.write("Time Cost:%d seconds" % (decode_cost))
|
| 111 |
|
| 112 |
|
| 113 |
-
def load_model(resume_path):
|
| 114 |
-
n_fft = 1000
|
| 115 |
-
hop_length = 400
|
| 116 |
-
# https://huggingface.co/M4869/InvertibleWM/blob/main/step59000_snr39.99_pesq4.35_BERP_none0.30_mean1.81_std1.81.pkl
|
| 117 |
-
# api_key = st.secrets["api_key"]
|
| 118 |
-
# print(api_key, api_key)
|
| 119 |
-
api_key = "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"
|
| 120 |
-
model_ckpt_path = hf_hub_download(repo_id="M4869/InvertibleWM",
|
| 121 |
-
filename="step59000_snr39.99_pesq4.35_BERP_none0.30_mean1.81_std1.81.pkl",
|
| 122 |
-
token=api_key
|
| 123 |
-
)
|
| 124 |
-
# print("model_ckpt_path", model_ckpt_path)
|
| 125 |
-
resume_path = model_ckpt_path
|
| 126 |
-
# return
|
| 127 |
-
|
| 128 |
-
model = my_model_v7_recover.Model(16000, 32, n_fft, hop_length,
|
| 129 |
-
use_recover_layer=False, num_layers=8).to(device)
|
| 130 |
-
checkpoint = torch.load(resume_path, map_location=torch.device('cpu'))
|
| 131 |
-
state_dict = model_util.map_state_dict(checkpoint['model'])
|
| 132 |
-
model.load_state_dict(state_dict, strict=True)
|
| 133 |
-
model.eval()
|
| 134 |
-
return model
|
| 135 |
-
|
| 136 |
-
|
| 137 |
if __name__ == "__main__":
|
| 138 |
-
len_start_bit =
|
| 139 |
|
| 140 |
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
|
| 141 |
-
|
| 142 |
-
model = load_model("./data/step59000_snr39.99_pesq4.35_BERP_none0.30_mean1.81_std1.81.pkl")
|
| 143 |
|
| 144 |
main()
|
| 145 |
-
# decode_watermark("/Users/my/Downloads/7a95b353a46893903e9f946c24170b210ce14e8c52c63bb2ab3d144e.wav")
|
|
|
|
| 1 |
import pdb
|
| 2 |
import time
|
| 3 |
+
import wavmark
|
|
|
|
| 4 |
import streamlit as st
|
| 5 |
import os
|
|
|
|
|
|
|
| 6 |
import torch
|
| 7 |
import uuid
|
| 8 |
import datetime
|
| 9 |
import numpy as np
|
| 10 |
import soundfile
|
| 11 |
from huggingface_hub import hf_hub_download, HfApi
|
| 12 |
+
from wavmark.utils import file_reader
|
| 13 |
|
| 14 |
|
| 15 |
# Function to add watermark to audio
|
| 16 |
def add_watermark(audio_path, watermark_text):
|
| 17 |
+
assert len(watermark_text) == 16
|
| 18 |
+
watermark_npy = np.array([int(i) for i in watermark_text])
|
| 19 |
+
# todo: 控制时间
|
| 20 |
|
| 21 |
+
signal, sr, audio_length_second = file_reader.read_as_single_channel_16k(audio_path, 16000)
|
| 22 |
+
watermarked_signal, _ = wavmark.encode_watermark(model, signal, watermark_npy, show_progress=False)
|
|
|
|
| 23 |
|
| 24 |
tmp_file_name = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S') + "_" + str(uuid.uuid4()) + ".wav"
|
| 25 |
tmp_file_path = '/tmp/' + tmp_file_name
|
| 26 |
+
soundfile.write(tmp_file_path, watermarked_signal, sr)
|
| 27 |
return tmp_file_path
|
| 28 |
|
| 29 |
|
| 30 |
# Function to decode watermark from audio
|
| 31 |
def decode_watermark(audio_path):
|
| 32 |
+
watermarked_signal, sr, audio_length_second = file_reader.read_as_single_channel_16k(audio_path, 16000)
|
| 33 |
+
payload_decoded, _ = wavmark.decode_watermark(model, watermarked_signal, show_progress=False)
|
| 34 |
+
|
| 35 |
+
if payload_decoded is None:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
return "No Watermark"
|
| 37 |
|
| 38 |
+
return payload_decoded
|
|
|
|
| 39 |
|
| 40 |
|
| 41 |
# Main web app
|
| 42 |
def main():
|
| 43 |
+
max_upload_size = 20 * 1024 * 1024 # 20 MB in bytes
|
| 44 |
+
|
| 45 |
if "def_value" not in st.session_state:
|
| 46 |
+
def_val_npy = np.random.choice([0, 1], size=32 - len_start_bit)
|
| 47 |
+
def_val_str = "".join([str(i) for i in def_val_npy])
|
| 48 |
+
st.session_state.def_value = def_val_str
|
| 49 |
|
| 50 |
st.title("Neural Audio Watermark")
|
| 51 |
st.write("Choose the action you want to perform:")
|
|
|
|
| 53 |
action = st.selectbox("Select Action", ["Add Watermark", "Decode Watermark"])
|
| 54 |
|
| 55 |
if action == "Add Watermark":
|
| 56 |
+
audio_file = st.file_uploader("Upload Audio File (WAV)", type=["wav"], accept_multiple_files=False,
|
| 57 |
+
max_upload_size=max_upload_size)
|
| 58 |
if audio_file:
|
| 59 |
tmp_input_audio_file = os.path.join("/tmp/", audio_file.name)
|
| 60 |
with open(tmp_input_audio_file, "wb") as f:
|
| 61 |
f.write(audio_file.getbuffer())
|
| 62 |
st.audio(tmp_input_audio_file, format="audio/wav")
|
| 63 |
|
| 64 |
+
watermark_text = st.text_input("Enter Watermark", value=st.session_state.def_value)
|
| 65 |
|
| 66 |
add_watermark_button = st.button("Add Watermark", key="add_watermark_btn")
|
| 67 |
if add_watermark_button: # 点击按钮后执行的
|
|
|
|
| 82 |
# st.button("Add Watermark", disabled=False)
|
| 83 |
|
| 84 |
elif action == "Decode Watermark":
|
| 85 |
+
audio_file = st.file_uploader("Upload Audio File (WAV/MP3)", type=["wav", "mp3"], accept_multiple_files=False,
|
| 86 |
+
max_upload_size=max_upload_size)
|
| 87 |
if audio_file:
|
| 88 |
if st.button("Decode Watermark"):
|
| 89 |
# 1.保存
|
|
|
|
| 103 |
st.write("Time Cost:%d seconds" % (decode_cost))
|
| 104 |
|
| 105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
if __name__ == "__main__":
|
| 107 |
+
len_start_bit = 16
|
| 108 |
|
| 109 |
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
|
| 110 |
+
model = wavmark.load_model().to(device)
|
|
|
|
| 111 |
|
| 112 |
main()
|
|
|
requirements.txt
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
|
|
| 1 |
soundfile
|
| 2 |
librosa
|
| 3 |
-
resampy
|
| 4 |
-
torch==1.13.1
|
| 5 |
-
torchvision==0.14.1
|
| 6 |
-
torchaudio==0.13.1
|
|
|
|
| 1 |
+
wavmark
|
| 2 |
soundfile
|
| 3 |
librosa
|
| 4 |
+
resampy
|
|
|
|
|
|
|
|
|