直接上代码:
编码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
import numpy as np import soundfile as sf from scipy.fftpack import dct, idct def embed_watermark(audio_file, watermark, output_file): # 读取音频文件 audio_data, sample_rate = sf.read(audio_file) # 进行 DCT 变换 dct_data = dct(audio_data, type=2, norm='ortho') # 确保水印长度不超过 DCT 数据长度 if len(watermark) > len(dct_data): raise ValueError("Watermark is longer than the DCT data.") # 嵌入水印 for i in range(len(watermark)): # 在 DCT 系数中嵌入水印(简单加法) if watermark[i] == 1: dct_data[i] += 0.1 # 增加值 else: dct_data[i] -= 0.1 # 减少值 # 进行逆 DCT 变换 watermarked_audio = idct(dct_data, type=2, norm='ortho') # 确保音频数据在有效范围内 watermarked_audio = np.clip(watermarked_audio, -1.0, 1.0) # 导出带水印的音频 sf.write(output_file, watermarked_audio, sample_rate) def main(): original_audio_file = 'original_audio.mp3' # 原始音频文件路径 watermark = [1, 0, 1, 1, 0, 1, 0, 1] # 示例水印(可以是二进制数据) output_audio_file = 'watermarked_audio.mp3' # 输出文件路径 embed_watermark(original_audio_file, watermark, output_audio_file) if __name__ == "__main__": main() |
解码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import numpy as np import soundfile as sf from scipy.fftpack import dct def extract_watermark(watermarked_audio_file, watermark_length): # 读取带水印的音频文件 watermarked_audio_data, sample_rate = sf.read(watermarked_audio_file) # 进行 DCT 变换 dct_data = dct(watermarked_audio_data, type=2, norm='ortho') # 提取水印 extracted_watermark = [] for i in range(watermark_length): # 检查 DCT 系数的变化 if dct_data[i] > 0: # 假设嵌入时增加了值 extracted_watermark.append(1) else: # 假设嵌入时减少了值 extracted_watermark.append(0) return extracted_watermark def main(): watermarked_audio_file = 'watermarked_audio3.mp3' # 带水印的音频文件路径 watermark_length = 8 # 水印长度(与嵌入时一致) extracted_watermark = extract_watermark(watermarked_audio_file, watermark_length) print("Extracted Watermark:", extracted_watermark) if __name__ == "__main__": main() |