1、首先需要下载FFmpeg;

2、Gradle依赖

def void forceVersion(details, group, version) {
if (details.requested.group == group) {
details.useVersion version
}
} def void forceVersion(details, group, name, version) {
if (details.requested.group == group && details.requested.name == name) {
details.useVersion version
}
} allprojects { p ->
group = 'com.my.spider'
version = '1.0.0' apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'maven-publish' [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' jar.doFirst {
manifest {
def manifestFile = "${projectDir}/META-INF/MANIFEST.MF"
if (new File(manifestFile).exists())
from (manifestFile) attributes 'Implementation-Title':p.name
if (p.version.endsWith('-SNAPSHOT')) {
attributes 'Implementation-Version': p.version + '-' + p.ext.Timestamp
} else {
attributes 'Implementation-Version': p.version
}
attributes 'Implementation-BuildDateTime':new Date()
}
} javadoc {
options {
encoding 'UTF-8'
charSet 'UTF-8'
author false
version true
links 'http://docs.oracle.com/javase/8/docs/api/index.html'
memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PRIVATE
}
} if (System.env.uploadArchives) {
build.dependsOn publish
} buildscript {
repositories {
mavenCentral()
}
dependencies {classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.14.RELEASE' }
} afterEvaluate {Project project ->
if (project.pluginManager.hasPlugin('java')) {
configurations.all {
resolutionStrategy.eachDependency {DependencyResolveDetails details ->
forceVersion details, 'org.springframework.boot', '1.4.1.RELEASE'
forceVersion details, 'org.slf4j', '1.7.21'
forceVersion details, 'org.springframework', '4.3.3.RELEASE'
} exclude module:'slf4j-log4j12'
exclude module:'log4j'
} dependencies {testCompile 'junit:junit:4.12' }
}
} repositories {
mavenCentral()
} // 时间戳:年月日时分
p.ext.Timestamp = new Date().format('yyyyMMddHHmm')
// Build Number
p.ext.BuildNumber = System.env.BUILD_NUMBER
if (p.ext.BuildNumber == null || "" == p.ext.BuildNumber) {
p.ext.BuildNumber = 'x'
}
} task zipSources(type: Zip) {
description '压缩源代码'
project.ext.zipSourcesFile = project.name + '-' + project.version + '-' + project.ext.Timestamp + '.' + project.ext.BuildNumber + '-sources.zip'
archiveName = project.ext.zipSourcesFile
includeEmptyDirs = false from project.projectDir exclude '**/.*'
exclude 'build/*'
allprojects.each { p ->
exclude '**/' + p.name + '/bin/*'
exclude '**/' + p.name + '/build/*'
exclude '**/' + p.name + '/data/*'
exclude '**/' + p.name + '/work/*'
exclude '**/' + p.name + '/logs/*'
}
} def CopySpec appCopySpec(Project prj, dstname = null) {
if (!dstname) { dstname = prj.name }
return copySpec{
// Fat jar
from (prj.buildDir.toString() + '/libs/' + prj.name + '-' + project.version + '.jar') {
into dstname
} // Configs
from (prj.projectDir.toString() + '/config/examples') {
into dstname + '/config'
} // Windows start script
from (prj.projectDir.toString() + '/' + prj.name + '.bat') {
into dstname
} // Unix conf script
from (prj.projectDir.toString() + '/' + prj.name + '.conf') {
into dstname
rename prj.name, prj.name + '-' + project.version
}
}
} task zipSetup(type: Zip, dependsOn: subprojects.build) {
description '制作安装包'
project.ext.zipSetupFile = project.name + '-' + project.version + '-' + project.ext.Timestamp + '.' + project.ext.BuildNumber + '-setup.zip'
archiveName = project.name + '-' + project.version + '-' + project.ext.Timestamp + '.' + project.ext.BuildNumber + '-setup.zip' with appCopySpec(project(':spider-demo'))
} import java.security.MessageDigest def generateMD5(final file) {
MessageDigest digest = MessageDigest.getInstance("MD5")
file.withInputStream(){is->
byte[] buffer = new byte[8192]
int read = 0
while( (read = is.read(buffer)) > 0) {
digest.update(buffer, 0, read);
}
}
byte[] md5sum = digest.digest()
BigInteger bigInt = new BigInteger(1, md5sum)
return bigInt.toString(16)
} task md5(dependsOn: [zipSetup, zipSources]) << {
String md5_setup = generateMD5(file("${projectDir}/build/distributions/" + project.ext.zipSetupFile));
String md5_sources = generateMD5(file("${projectDir}/build/distributions/" + project.ext.zipSourcesFile));
println project.ext.zipSetupFile + '=' + md5_setup
println project.ext.zipSourcesFile + '=' + md5_sources def newFile = new File("${projectDir}/build/distributions/"
+ project.name + '-' + project.version + '-' + project.ext.Timestamp + '.' + project.ext.BuildNumber + '-md5.txt')
PrintWriter printWriter = newFile.newPrintWriter()
printWriter.println project.ext.zipSetupFile + '=' + md5_setup
printWriter.println project.ext.zipSourcesFile + '=' + md5_sources
printWriter.flush()
printWriter.close()
} build.dependsOn subprojects.build, zipSetup, zipSources, md5

bulid.gradle

工程组件gradle依赖: 语音识别使用 百度api;需引入 compile 'com.baidu.aip:java-sdk:3.2.1'

apply plugin: 'spring-boot'
apply plugin: 'application' distributions {
main {
contents {
from ("${projectDir}/config/examples") {
into "config"
}
}
}
} distTar.enabled = false springBoot {
executable = true
mainClass = 'com.my.ai.Application'
} dependencies {
compile 'org.springframework.boot:spring-boot-starter-web:1.4.0.RELEASE'
compile 'dom4j:dom4j:1.6.1'
compile 'commons-httpclient:commons-httpclient:3.1'
compileOnly 'com.h2database:h2:1.4.191'
compile 'javax.cache:cache-api:1.0.0'
compile 'org.jboss.resteasy:resteasy-jaxrs:3.0.14.Final'
compile 'org.jboss.resteasy:resteasy-client:3.0.14.Final'
// Axis
compile 'axis:axis:1.4' compile 'org.jsoup:jsoup:1.10.1' compile 'com.alibaba:fastjson:1.2.21' compile 'com.baidu.aip:java-sdk:3.2.1' }

3、视频抽取音频服务“

package com.my.ai.service;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.List; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; //视频抽取音频
@Service
public class ExtractAudioService { public static Logger logger = LoggerFactory.getLogger(ExtractAudioService.class); public static void main(String[] args) {
new ExtractAudioService().getAudioFromVideo("E:\\QLDownload\\氧化还原反应中电子转移的方向和数目的表示方法\\氧化还原反应中电子转移的方向和数目的表示方法.mp4",
"D:\\ffmpeg4.2\\bin\\ffmpeg.exe");
} public String getAudioFromVideo(String videoPath,String ffmpegPath) {
File video = new File(videoPath);
if(video.exists() && video.isFile()){
String format = "wav";
String outPath = videoPath.substring(0,videoPath.lastIndexOf(".")) + ".wav";
processCmd(videoPath, ffmpegPath, format, outPath);
return outPath;
}
return null;
} //D:\ffmpeg4.2\bin\ffmpeg.exe -i 氧化还原反应中电子转移的方向和数目的表示方法.mp4 -f wav -vn -y 3.wav
public String processCmd(String inputPath,String ffmpegPath,String format,String outPath) {
List<String> commend = new java.util.ArrayList<String>();
commend.add(ffmpegPath);
commend.add("-i");
commend.add(inputPath);
commend.add("-y");
commend.add("-vn");
commend.add("-f");
commend.add(format);
commend.add(outPath);
try { ProcessBuilder builder = new ProcessBuilder();
builder.command(commend);
builder.redirectErrorStream(true);
Process p = builder.start(); // 1. start
BufferedReader buf = null; // 保存ffmpeg的输出结果流
String line = null;
// read the standard output buf = new BufferedReader(new InputStreamReader(p.getInputStream())); StringBuffer sb = new StringBuffer();
while ((line = buf.readLine()) != null) {
System.out.println(line);
sb.append(line);
continue;
}
p.waitFor();// 这里线程阻塞,将等待外部转换进程运行成功运行结束后,才往下执行
// 1. end
return sb.toString();
} catch (Exception e) {
// System.out.println(e);
return null;
}
} }

ExtractAudioService

4、音频切段:

package com.my.ai.service;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; @Service
public class CutService { public static Logger logger = LoggerFactory.getLogger(CutService.class); public List<String> cutFile(String media_path, String ffmpeg_path) { List<String> audios = new ArrayList<>();
int mediaTime = getMediaTime(media_path, ffmpeg_path);
int num = mediaTime / 59;
int lastNum = mediaTime % 59;
System.out.println(mediaTime +"|" + num + "|"+ lastNum);
int length = 59;
File file = new File(media_path);
String filename = file.getName();
for (int i = 0; i < num; i++) {
String outputPath = file.getParent() + File.separator + i + "-"+filename;
processCmd(media_path, ffmpeg_path, String.valueOf(length * i) ,
String.valueOf(length), outputPath);
audios.add(outputPath);
}
if(lastNum > 0) {
String outputPath = file.getParent() + File.separator + num + "-"+filename;
processCmd(media_path, ffmpeg_path, String.valueOf(length * num) ,
String.valueOf(lastNum), outputPath);
audios.add(outputPath);
}
return audios;
} /**
* 获取视频总时间
*
* @param viedo_path 视频路径
* @param ffmpeg_path ffmpeg路径
* @return
*/
public int getMediaTime(String video_path, String ffmpeg_path) {
List<String> commands = new java.util.ArrayList<String>();
commands.add(ffmpeg_path);
commands.add("-i");
commands.add(video_path);
try {
ProcessBuilder builder = new ProcessBuilder();
builder.command(commands);
final Process p = builder.start(); // 从输入流中读取视频信息
BufferedReader br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
System.out.println(sb.toString());
br.close(); // 从视频信息中解析时长
String regexDuration = "Duration: (.*?), bitrate: (\\d*) kb\\/s";
Pattern pattern = Pattern.compile(regexDuration);
Matcher m = pattern.matcher(sb.toString());
if (m.find()) {
int time = getTimelen(m.group(1));
System.out
.println(video_path + ",视频时长:" + time + ",比特率:" + m.group(2) + "kb/s");
return time;
}
} catch (Exception e) {
e.printStackTrace();
}
return 0;
} // 格式:"00:00:10.68"
public int getTimelen(String timelen) {
int min = 0;
String strs[] = timelen.split(":");
if (strs[0].compareTo("0") > 0) {
min += Integer.valueOf(strs[0]) * 60 * 60;// 秒
}
if (strs[1].compareTo("0") > 0) {
min += Integer.valueOf(strs[1]) * 60;
}
if (strs[2].compareTo("0") > 0) {
min += Math.round(Float.valueOf(strs[2]));
}
return min;
} //D:\ffmpeg4.2\bin\ffmpeg.exe -i 123.pcm -ss 0 -t 59 1-123.wav
public String processCmd(String inputPath,String ffmpegPath,
String startTime,String length,String outputPath) {
List<String> commend = new java.util.ArrayList<String>();
commend.add(ffmpegPath);
commend.add("-i");
commend.add(inputPath);
commend.add("-ss");
commend.add(startTime);
commend.add("-t");
commend.add(length);
commend.add(outputPath);
try { ProcessBuilder builder = new ProcessBuilder();
builder.command(commend);
builder.redirectErrorStream(true);
Process p = builder.start(); // 1. start
BufferedReader buf = null; // 保存ffmpeg的输出结果流
String line = null;
// read the standard output buf = new BufferedReader(new InputStreamReader(p.getInputStream())); StringBuffer sb = new StringBuffer();
while ((line = buf.readLine()) != null) {
System.out.println(line);
sb.append(line);
continue;
}
p.waitFor();// 这里线程阻塞,将等待外部转换进程运行成功运行结束后,才往下执行
// 1. end
return sb.toString();
} catch (Exception e) {
System.out.println(e);
return null;
}
} //ffmpeg -y -i 16k.wav -acodec pcm_s16le -f s16le -ac 1 -ar 16000 16k.pcm
public static String processWavToPcm(String inputPath,String ffmpegPath,String outputPath) {
List<String> commend = new java.util.ArrayList<String>();
commend.add(ffmpegPath);
commend.add("-i");
commend.add(inputPath);
commend.add("-acodec");
commend.add("pcm_s16le");
commend.add("-f");
commend.add("s16le");
commend.add("-ac");
commend.add("1");
commend.add("-ar");
commend.add("16000");
commend.add(outputPath);
try { ProcessBuilder builder = new ProcessBuilder();
builder.command(commend);
builder.redirectErrorStream(true);
Process p = builder.start(); // 1. start
BufferedReader buf = null; // 保存ffmpeg的输出结果流
String line = null;
// read the standard output buf = new BufferedReader(new InputStreamReader(p.getInputStream())); StringBuffer sb = new StringBuffer();
while ((line = buf.readLine()) != null) {
System.out.println(line);
sb.append(line);
continue;
}
p.waitFor();// 这里线程阻塞,将等待外部转换进程运行成功运行结束后,才往下执行
// 1. end
return outputPath;
//sb.toString();
} catch (Exception e) {
System.out.println(e);
return null;
}
} public static void main(String[] args) {
List<String> audios = new CutService().cutFile(
"E:\\QLDownload\\氧化还原反应中电子转移的方向和数目的表示方法\\氧化还原反应中电子转移的方向和数目的表示方法.wav",
"D:\\ffmpeg4.2\\bin\\ffmpeg.exe");
System.out.println(audios.size()); for (String wavPath : audios) {
String out = wavPath.substring(0,wavPath.lastIndexOf(".")) + ".pcm";
processWavToPcm(wavPath, "D:\\ffmpeg4.2\\bin\\ffmpeg.exe", out);
} } }

5、音频格式转换,便于进行语音识别,代码如上:

6、调用sdk,获取识别结果:

package com.my.ai.service;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import com.baidu.aip.speech.AipSpeech; @Service
public class TokenService { public static Logger logger = LoggerFactory.getLogger(TokenService.class); //设置APPID/AK/SK
public static final String APP_ID = "***";
public static final String API_KEY = "***";
public static final String SECRET_KEY = "***";
static AipSpeech client = null;
static {
if(client == null) {
client = new AipSpeech(APP_ID, API_KEY, SECRET_KEY);
}
} public static void main(String[] args) {
getResult("E:\\QLDownload\\氧化还原反应中电子转移的方向和数目的表示方法\\0-氧化还原反应中电子转移的方向和数目的表示方法.pcm");
} public static String getResult(String file) { // 可选:设置网络连接参数
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);
// 可选:设置代理服务器地址, http和socket二选一,或者均不设置
//client.setHttpProxy("proxy_host", proxy_port); // 设置http代理
//client.setSocketProxy("proxy_host", proxy_port); // 设置socket代理
JSONObject res = client.asr(file, "pcm", 16000, null);
//System.out.println(res.toString(2));
System.out.println(res.get("result").toString());
return res.get("result").toString();
} }

  

7、结果写入文件:

package com.my.ai.service;

import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; @Service
public class FileService { public static Logger logger = LoggerFactory.getLogger(FileService.class); //最慢
public static void writeFile1(String file,String content) throws IOException {
FileOutputStream out = null;
out = new FileOutputStream(new File(file));
long begin = System.currentTimeMillis();
out.write(content.getBytes());
out.close();
long end = System.currentTimeMillis();
System.out.println("FileOutputStream执行耗时:" + (end - begin) + " 毫秒");
}
//中
public static void writeFile2(String file,String content) throws IOException{
FileWriter fw = null;
fw = new FileWriter(file);
long begin3 = System.currentTimeMillis();
fw.write(content);
fw.close();
long end3 = System.currentTimeMillis();
System.out.println("FileWriter执行耗时:" + (end3 - begin3) + " 毫秒");
}
//最快
public static void writeFile3(String file,String content) throws IOException{
FileOutputStream outSTr = null;
BufferedOutputStream buff = null;
outSTr = new FileOutputStream(new File(file));
buff = new BufferedOutputStream(outSTr);
long begin0 = System.currentTimeMillis();
buff.write(content.getBytes());
buff.flush();
buff.close();
long end0 = System.currentTimeMillis();
System.out.println("BufferedOutputStream执行耗时:" + (end0 - begin0) + " 毫秒");
} public static void main(String[] args) {
for (int i = 0; i < 7; i++) {
String result = TokenService.getResult("E:\\QLDownload\\氧化还原反应中电子转移的方向和数目的表示方法\\" + i +"-氧化还原反应中电子转移的方向和数目的表示方法.pcm");
appendFile2("E:\\QLDownload\\氧化还原反应中电子转移的方向和数目的表示方法\\氧化还原反应中电子转移的方向和数目的表示方法.txt", result+"\r\n");
}
} public static void appendFile1(String file, String conent) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
out.write(conent);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 追加文件:使用FileWriter
*
* @param fileName
* @param content
*/
public static void appendFile2(String fileName, String content) {
FileWriter writer = null;
try {
// 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件
writer = new FileWriter(fileName, true);
writer.write(content);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 追加文件:使用RandomAccessFile
*
* @param fileName 文件名
* @param content 追加的内容
*/
public static void appendFile3(String fileName, String content) {
RandomAccessFile randomFile = null;
try {
// 打开一个随机访问文件流,按读写方式
randomFile = new RandomAccessFile(fileName, "rw");
// 文件长度,字节数
long fileLength = randomFile.length();
// 将写文件指针移到文件尾。
randomFile.seek(fileLength);
randomFile.writeBytes(content);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (randomFile != null) {
try {
randomFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} }

 

8、测试:

package com.my.ai.test;

import java.util.List;

import com.my.ai.service.CutService;
import com.my.ai.service.ExtractAudioService;
import com.my.ai.service.FileService;
import com.my.ai.service.TokenService; public class TestService { public static void main(String[] args) {
ExtractAudioService audioService = new ExtractAudioService();
String outPath = audioService.getAudioFromVideo("G:\\Youku Files\\transcode\\化学高中必修1__第2章第3节·氧化还原反应_标清.mp4", "D:\\ffmpeg4.2\\bin\\ffmpeg.exe");
List<String> audios = new CutService().cutFile(outPath,"D:\\ffmpeg4.2\\bin\\ffmpeg.exe");
for (String wavPath : audios) {
String out = wavPath.substring(0,wavPath.lastIndexOf(".")) + ".pcm";
String outPcm = CutService.processWavToPcm(wavPath, "D:\\ffmpeg4.2\\bin\\ffmpeg.exe", out);
String result = TokenService.getResult(outPcm);
FileService.appendFile2("G:\\Youku Files\\transcode\\化学高中必修1__第2章第3节·氧化还原反应_标清.mp4-字幕.txt", result+"\r\n");
}
} }

  

使用FFmpeg进行视频抽取音频,之后进行语音识别转为文字的更多相关文章

  1. ffmpeg实现视频文件合并/截取预览视频/抽取音频/crop(裁剪)(ffmpeg4.2.2)

    一,ffmpeg的安装 请参见: https://www.cnblogs.com/architectforest/p/12807683.html 说明:刘宏缔的架构森林是一个专注架构的博客,地址:ht ...

  2. 在java中使用FFmpeg处理视频与音频

    FFmpeg是一个非常好用的视频处理工具,下面讲讲如何在java中使用该工具类. 一.首先,让我们来认识一下FFmpeg在Dos界面的常见操作 1.拷贝视频,并指定新的视频的名字以及格式 ffmpeg ...

  3. FFmpeg开发实战(四):FFmpeg 抽取音视频的音频数据

    如何使用FFmpeg抽取音视频的音频数据,代码如下: void adts_header(char *szAdtsHeader, int dataLen); // 使用FFmpeg从视频中抽取音频 vo ...

  4. FFmpeg进行视频帧提取&音频重采样-Process.waitFor()引发的阻塞超时

    由于产品需要对视频做一系列的解析操作,利用FFmpeg命令来完成视频的音频提取.第一帧提取作为封面图片.音频重采样.字幕压缩等功能: 前一篇文章已经记录了FFmpeg在JAVA中的使用-音频提取&am ...

  5. Java使用FFmpeg处理视频文件指南

    Java使用FFmpeg处理视频文件指南 本文主要讲述如何使用Java + FFmpeg实现对视频文件的信息提取.码率压缩.分辨率转换等功能: 之前在网上浏览了一大圈Java使用FFmpeg处理音视频 ...

  6. Java使用FFmpeg处理视频文件的方法教程

    这篇文章主要给大家介绍了关于Java使用FFmpeg处理视频文件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧 前言 本文主要 ...

  7. ffmpeg为视频添加时间戳 - 手动编译ffmpeg

    FFMPEG给视频加时间戳水印 项目中需要给视频添加时间戳,理所当然最好用的办法是ffmpeg.在找到正确的做法前,还被网上的答案timecode给水了一下(水的不轻,在这里转了2天),大概是这样写的 ...

  8. 使用ffmpeg 对视频截图,和视频转换格式

    //执行CMD命令方法 public static void CmdProcess(string command)//调用CMD        {            //实例化一个进程类      ...

  9. NET 2.0(C#)调用ffmpeg处理视频的方法

    另外:ffmpeg的net封装库 http://www.intuitive.sk/fflib/ NET 2.0 调用FFMPEG,并异步读取输出信息的代码...public void ConvertV ...

随机推荐

  1. Openssl pkcs12命令

    一.简介 pkcs12命令能生成和分析pkcs12文件 二.语法 openssl pkcs12 [-export] [-chain] [-inkey filename] [-certfile file ...

  2. Use formatter to format your JAVA code

    In order to make the codes looks unified and make it easy to understand, it's better to use the same ...

  3. Requests接口测试-对cookies的操作处理(二)

    我们继续来讨论一下cookie这方面的内容,我们都知道cookie是数据,一般的话在我接口测试中,数据都是要和代码进行分离的.本篇内容,我们队cookie内容进行处理,我们把登陆成功后的cookie写 ...

  4. Dubbo的配置及启动

    Tomcat+Dubbo安装 1.将tomcat的webapps目录下的所有文件清空,讲Dubbo管理控制台的程序dubbo-admin-2.5.3.war放 到webapps中,并且解压命名为ROO ...

  5. g++中宏NULL究竟是什么?

    NULL是个指针,还是个整数?0?或(void*)0?答案是和g++版本有关.g++ 4.6支持C++11,引入了nullptr,也许会发生变化. 可以写段简单代码求证一下: #include < ...

  6. WCF服务编程 读书笔记——第1章 WCF基础(1)

    第1章 WCF基础 本章主要介绍WCF的基本概念.构建模块以及WCF体系架构,以指导读者构建一个简单的WCF服务.从本章的内容中,我们可以了解到WCF的基本术语,包括地址(Address).绑定(Bi ...

  7. python字符串字典列表互转

    #-*-coding:utf-8-*- #1.字典 dict = {'name': 'Zara', 'age': 7, 'class': 'First'} #字典转为字符串,返回:<type ' ...

  8. CodeForces 327E Axis Walking(状压DP+卡常技巧)

    Iahub wants to meet his girlfriend Iahubina. They both live in Ox axis (the horizontal axis). Iahub ...

  9. CSS中的一些内容总结

    一.选择器 1.选择器的分组:一个Style可以对多个选择器生效,只用在不同的选择器中间加入逗号即可.如: h1,h2,h3,h4,h5,h6 { color: green; } PS:CSS规定,所 ...

  10. 基于JSP的B2C的网上拍卖系统_秒杀与竞价-JavaWeb项目-有源码

    开发工具:Myeclipse/Eclipse + MySQL + Tomcat 项目简介: 基于B2C的网上拍卖系统主要用于帮助人们应用互联网方便快捷买到自己所中意的商品,并参与到秒杀与竞拍当中.主要 ...