JavaScript (Node.js), 131131 128 bytes
s=>unescape(s.replace(r=/B.(D.)?/g,(f,s)=>(-~g(f[1])*4*!!s+g((s||f)[1])).toString(16),g=c=>'IAOU'.indexOfsearch(c)).replace(/../g,'%$&'))
Try it online!Try it online! Link includes test cases. Alternative version, also 131 bytes:
s=>unescape(s.replace(r=/B.(D.)?/g,s=>(-~g(s[1])*4*!!s[3]+g(s[3]||s[1])).toString(16),g=c=>'IAOU'.indexOfsearch(c)).replace(/../g,'%$&'))
Try it online!Try it online! Link includes test cases. Edit: Saves 3 bytes thanks to @Shaggy.